@@ -34,6 +34,26 @@ function deferredPromises(count: number): Array<Deferred<void>> {
34
34
return deferred ;
35
35
}
36
36
37
+ function assertOpCount < T > (
38
+ pool : ClientPool < T > ,
39
+ grpcClientOpCount : number ,
40
+ restClientOpCount : number
41
+ ) : void {
42
+ let actualGrpcClientOpCount = 0 ;
43
+ let actualRestClientOpCount = 0 ;
44
+
45
+ pool . _activeClients . forEach ( clientConfig => {
46
+ if ( clientConfig . grpcEnabled ) {
47
+ actualGrpcClientOpCount += clientConfig . activeRequestCount ;
48
+ } else {
49
+ actualRestClientOpCount += clientConfig . activeRequestCount ;
50
+ }
51
+ } ) ;
52
+
53
+ expect ( actualGrpcClientOpCount ) . to . equal ( grpcClientOpCount ) ;
54
+ expect ( actualRestClientOpCount ) . to . equal ( restClientOpCount ) ;
55
+ }
56
+
37
57
describe ( 'Client pool' , ( ) => {
38
58
it ( 'creates new instances as needed' , ( ) => {
39
59
const clientPool = new ClientPool < { } > ( 3 , 0 , ( ) => {
@@ -133,6 +153,7 @@ describe('Client pool', () => {
133
153
( ) => operationPromises [ 1 ] . promise
134
154
) ;
135
155
expect ( clientPool . size ) . to . equal ( 2 ) ;
156
+ assertOpCount ( clientPool , 1 , 1 ) ;
136
157
137
158
operationPromises [ 0 ] . resolve ( ) ;
138
159
operationPromises [ 1 ] . resolve ( ) ;
@@ -156,9 +177,166 @@ describe('Client pool', () => {
156
177
( ) => operationPromises [ 1 ] . promise
157
178
) ;
158
179
expect ( clientPool . size ) . to . equal ( 1 ) ;
180
+ assertOpCount ( clientPool , 2 , 0 ) ;
181
+
182
+ operationPromises [ 0 ] . resolve ( ) ;
183
+ operationPromises [ 1 ] . resolve ( ) ;
184
+ } ) ;
185
+
186
+ it ( 'does not re-use rest instance after beginning the transition to grpc' , async ( ) => {
187
+ const clientPool = new ClientPool < { } > ( 10 , 1 , ( ) => {
188
+ return { } ;
189
+ } ) ;
190
+
191
+ const operationPromises = deferredPromises ( 3 ) ;
192
+
193
+ void clientPool . run (
194
+ REQUEST_TAG ,
195
+ USE_REST ,
196
+ ( ) => operationPromises [ 0 ] . promise
197
+ ) ;
198
+ void clientPool . run (
199
+ REQUEST_TAG ,
200
+ USE_GRPC ,
201
+ ( ) => operationPromises [ 1 ] . promise
202
+ ) ;
203
+ void clientPool . run (
204
+ REQUEST_TAG ,
205
+ USE_REST ,
206
+ ( ) => operationPromises [ 2 ] . promise
207
+ ) ;
208
+
209
+ expect ( clientPool . size ) . to . equal ( 2 ) ;
210
+ assertOpCount ( clientPool , 2 , 1 ) ;
159
211
160
212
operationPromises [ 0 ] . resolve ( ) ;
161
213
operationPromises [ 1 ] . resolve ( ) ;
214
+ operationPromises [ 2 ] . resolve ( ) ;
215
+ } ) ;
216
+
217
+ it ( 'does not re-use rest instance after beginning the transition to grpc - rest operation resolved' , async ( ) => {
218
+ const clientPool = new ClientPool < { } > ( 10 , 1 , ( ) => {
219
+ return { } ;
220
+ } ) ;
221
+
222
+ const operationPromises = deferredPromises ( 3 ) ;
223
+
224
+ const restOperation = clientPool . run (
225
+ REQUEST_TAG ,
226
+ USE_REST ,
227
+ ( ) => operationPromises [ 0 ] . promise
228
+ ) ;
229
+ void clientPool . run (
230
+ REQUEST_TAG ,
231
+ USE_GRPC ,
232
+ ( ) => operationPromises [ 1 ] . promise
233
+ ) ;
234
+
235
+ // resolve rest operation
236
+ operationPromises [ 0 ] . resolve ( ) ;
237
+ await restOperation ;
238
+ expect ( clientPool . opCount ) . to . equal ( 1 ) ;
239
+
240
+ // Run new rest operation
241
+ void clientPool . run (
242
+ REQUEST_TAG ,
243
+ USE_REST ,
244
+ ( ) => operationPromises [ 2 ] . promise
245
+ ) ;
246
+
247
+ // Assert client pool status
248
+ expect ( clientPool . size ) . to . equal ( 1 ) ;
249
+ assertOpCount ( clientPool , 2 , 0 ) ;
250
+
251
+ operationPromises [ 1 ] . resolve ( ) ;
252
+ operationPromises [ 2 ] . resolve ( ) ;
253
+ } ) ;
254
+
255
+ it ( 'does not re-use rest instance after beginning the transition to grpc - grpc client full' , async ( ) => {
256
+ const operationLimit = 10 ;
257
+ const clientPool = new ClientPool < { } > ( operationLimit , 1 , ( ) => {
258
+ return { } ;
259
+ } ) ;
260
+
261
+ const restPromises = deferredPromises ( operationLimit ) ;
262
+ const grpcPromises = deferredPromises ( 1 ) ;
263
+
264
+ // First operation use GRPC
265
+ void clientPool . run ( REQUEST_TAG , USE_GRPC , ( ) => grpcPromises [ 0 ] . promise ) ;
266
+
267
+ // Next X operations can use rest, this will fill the first
268
+ // client and create a new client.
269
+ // The new client should use GRPC since we have transitioned.
270
+ restPromises . forEach ( restPromise => {
271
+ void clientPool . run ( REQUEST_TAG , USE_REST , ( ) => restPromise . promise ) ;
272
+ } ) ;
273
+ expect ( clientPool . opCount ) . to . equal ( 11 ) ;
274
+ expect ( clientPool . size ) . to . equal ( 2 ) ;
275
+ assertOpCount ( clientPool , 11 , 0 ) ;
276
+
277
+ grpcPromises . forEach ( grpcPromise => grpcPromise . resolve ( ) ) ;
278
+ restPromises . forEach ( restPromise => restPromise . resolve ( ) ) ;
279
+ } ) ;
280
+
281
+ it ( 'does not re-use rest instance after beginning the transition to grpc - multiple rest clients' , async ( ) => {
282
+ const operationLimit = 10 ;
283
+ const clientPool = new ClientPool < { } > ( operationLimit , 1 , ( ) => {
284
+ return { } ;
285
+ } ) ;
286
+
287
+ const restPromises = deferredPromises ( 15 ) ;
288
+ const grpcPromises = deferredPromises ( 5 ) ;
289
+
290
+ // First 15 operations can use rest, this will fill the first
291
+ // client and create a new client.
292
+ restPromises . forEach ( restPromise => {
293
+ void clientPool . run ( REQUEST_TAG , USE_REST , ( ) => restPromise . promise ) ;
294
+ } ) ;
295
+ expect ( clientPool . opCount ) . to . equal ( 15 ) ;
296
+ expect ( clientPool . size ) . to . equal ( 2 ) ;
297
+ assertOpCount ( clientPool , 0 , 15 ) ;
298
+
299
+ // Next 5 operations alternate between gRPC and REST, this will create a new client using gRPC
300
+ let transport = USE_GRPC ;
301
+ grpcPromises . forEach ( grpcPromise => {
302
+ void clientPool . run ( REQUEST_TAG , transport , ( ) => grpcPromise . promise ) ;
303
+ transport = ! transport ;
304
+ } ) ;
305
+ expect ( clientPool . opCount ) . to . equal ( 20 ) ;
306
+ expect ( clientPool . size ) . to . equal ( 3 ) ;
307
+ assertOpCount ( clientPool , 5 , 15 ) ;
308
+
309
+ grpcPromises . forEach ( grpcPromise => grpcPromise . resolve ( ) ) ;
310
+ restPromises . forEach ( restPromise => restPromise . resolve ( ) ) ;
311
+ } ) ;
312
+
313
+ it ( 'does not re-use rest instance after beginning the transition to grpc - grpc client RST_STREAM' , async ( ) => {
314
+ const clientPool = new ClientPool < { } > ( 10 , 1 , ( ) => {
315
+ return { } ;
316
+ } ) ;
317
+
318
+ const operationPromises = deferredPromises ( 1 ) ;
319
+
320
+ const grpcOperation = clientPool . run ( REQUEST_TAG , USE_GRPC , ( ) =>
321
+ Promise . reject (
322
+ new GoogleError ( '13 INTERNAL: Received RST_STREAM with code 2' )
323
+ )
324
+ ) ;
325
+
326
+ await grpcOperation . catch ( e => e ) ;
327
+
328
+ // Run new rest operation
329
+ void clientPool . run (
330
+ REQUEST_TAG ,
331
+ USE_REST ,
332
+ ( ) => operationPromises [ 0 ] . promise
333
+ ) ;
334
+
335
+ // Assert client pool status
336
+ expect ( clientPool . size ) . to . equal ( 1 ) ;
337
+ assertOpCount ( clientPool , 1 , 0 ) ;
338
+
339
+ operationPromises [ 0 ] . resolve ( ) ;
162
340
} ) ;
163
341
164
342
it ( 'bin packs operations' , async ( ) => {
0 commit comments