@@ -95,6 +95,10 @@ public class BatcherImpl<ElementT, ElementResultT, RequestT, ResponseT>
95
95
private final FlowController flowController ;
96
96
private final ApiCallContext callContext ;
97
97
98
+ private final long elementThreshold ;
99
+
100
+ private final long bytesThreshold ;
101
+
98
102
/**
99
103
* @param batchingDescriptor a {@link BatchingDescriptor} for transforming individual elements
100
104
* into wrappers request and response
@@ -192,7 +196,7 @@ public BatcherImpl(
192
196
+ "#maxOutstandingRequestBytes must be greater or equal to requestByteThreshold" );
193
197
}
194
198
this .flowController = flowController ;
195
- currentOpenBatch = new Batch <>(prototype , batchingDescriptor , batchingSettings , batcherStats );
199
+ currentOpenBatch = new Batch <>(prototype , batchingDescriptor , batcherStats );
196
200
if (batchingSettings .getDelayThreshold () != null ) {
197
201
long delay = batchingSettings .getDelayThreshold ().toMillis ();
198
202
PushCurrentBatchRunnable <ElementT , ElementResultT , RequestT , ResponseT > runnable =
@@ -204,6 +208,11 @@ public BatcherImpl(
204
208
}
205
209
currentBatcherReference = new BatcherReference (this );
206
210
this .callContext = callContext ;
211
+
212
+ Long elementCountThreshold = batchingSettings .getElementCountThreshold ();
213
+ this .elementThreshold = elementCountThreshold == null ? 0 : elementCountThreshold ;
214
+ Long requestByteThreshold = batchingSettings .getRequestByteThreshold ();
215
+ this .bytesThreshold = requestByteThreshold == null ? 0 : requestByteThreshold ;
207
216
}
208
217
209
218
/** {@inheritDoc} */
@@ -213,7 +222,7 @@ public ApiFuture<ElementResultT> add(ElementT element) {
213
222
// will only be done from a single calling thread.
214
223
Preconditions .checkState (closeFuture == null , "Cannot add elements on a closed batcher" );
215
224
216
- long bytesSize = batchingDescriptor .countBytes (element );
225
+ BatchResource newResource = batchingDescriptor .createResource (element );
217
226
218
227
// This is not the optimal way of throttling. It does not send out partial batches, which
219
228
// means that the Batcher might not use up all the resources allowed by FlowController.
@@ -232,20 +241,22 @@ public ApiFuture<ElementResultT> add(ElementT element) {
232
241
// defer it till we decide on if refactoring FlowController is necessary.
233
242
Stopwatch stopwatch = Stopwatch .createStarted ();
234
243
try {
235
- flowController .reserve (1 , bytesSize );
244
+ flowController .reserve (newResource . getElementCount (), newResource . getByteCount () );
236
245
} catch (FlowControlException e ) {
237
246
// This exception will only be thrown if the FlowController is set to ThrowException behavior
238
247
throw FlowControlRuntimeException .fromFlowControlException (e );
239
248
}
240
249
long throttledTimeMs = stopwatch .elapsed (TimeUnit .MILLISECONDS );
241
250
242
- if (!currentOpenBatch .isEmpty () && currentOpenBatch .batchFlusher .willBeFull (element )) {
251
+ if (!currentOpenBatch .isEmpty ()
252
+ && batchingDescriptor .shouldFlush (
253
+ currentOpenBatch .resource .add (newResource ), elementThreshold , bytesThreshold )) {
243
254
sendOutstanding ();
244
255
}
245
256
246
257
SettableApiFuture <ElementResultT > result = SettableApiFuture .create ();
247
258
synchronized (elementLock ) {
248
- currentOpenBatch .add (element , result , throttledTimeMs );
259
+ currentOpenBatch .add (element , newResource , result , throttledTimeMs );
249
260
}
250
261
251
262
return result ;
@@ -268,7 +279,7 @@ public void sendOutstanding() {
268
279
return ;
269
280
}
270
281
accumulatedBatch = currentOpenBatch ;
271
- currentOpenBatch = new Batch <>(prototype , batchingDescriptor , batchingSettings , batcherStats );
282
+ currentOpenBatch = new Batch <>(prototype , batchingDescriptor , batcherStats );
272
283
}
273
284
274
285
// This check is for old clients that instantiated the batcher without ApiCallContext
@@ -293,8 +304,8 @@ public void sendOutstanding() {
293
304
public void onSuccess (ResponseT response ) {
294
305
try {
295
306
flowController .release (
296
- accumulatedBatch .batchFlusher . getElementCounter (),
297
- accumulatedBatch .batchFlusher . getByteCounter ());
307
+ accumulatedBatch .resource . getElementCount (),
308
+ accumulatedBatch .resource . getElementCount ());
298
309
accumulatedBatch .onBatchSuccess (response );
299
310
} finally {
300
311
onBatchCompletion ();
@@ -305,8 +316,8 @@ public void onSuccess(ResponseT response) {
305
316
public void onFailure (Throwable throwable ) {
306
317
try {
307
318
flowController .release (
308
- accumulatedBatch .batchFlusher . getElementCounter (),
309
- accumulatedBatch .batchFlusher . getByteCounter ());
319
+ accumulatedBatch .resource . getElementCount (),
320
+ accumulatedBatch .resource . getByteCount ());
310
321
accumulatedBatch .onBatchFailure (throwable );
311
322
} finally {
312
323
onBatchCompletion ();
@@ -418,31 +429,30 @@ private static class Batch<ElementT, ElementResultT, RequestT, ResponseT> {
418
429
private final List <BatchEntry <ElementT , ElementResultT >> entries ;
419
430
private final BatchingDescriptor <ElementT , ElementResultT , RequestT , ResponseT > descriptor ;
420
431
421
- private final BatchFlusher <ElementT > batchFlusher ;
422
432
private final BatcherStats batcherStats ;
423
433
private long totalThrottledTimeMs = 0 ;
434
+ private BatchResource resource ;
424
435
425
436
private Batch (
426
437
RequestT prototype ,
427
438
BatchingDescriptor <ElementT , ElementResultT , RequestT , ResponseT > descriptor ,
428
- BatchingSettings batchingSettings ,
429
439
BatcherStats batcherStats ) {
430
440
this .descriptor = descriptor ;
431
441
this .builder = descriptor .newRequestBuilder (prototype );
432
442
this .entries = new ArrayList <>();
433
- Long elementCountThreshold = batchingSettings .getElementCountThreshold ();
434
- long elementThreshold = elementCountThreshold == null ? 0 : elementCountThreshold ;
435
- Long requestByteThreshold = batchingSettings .getRequestByteThreshold ();
436
- long bytesThreshold = requestByteThreshold == null ? 0 : requestByteThreshold ;
437
- this .batchFlusher = descriptor .newBatchFlusher (elementThreshold , bytesThreshold );
438
443
this .batcherStats = batcherStats ;
444
+ this .resource = descriptor .createEmptyResource ();
439
445
}
440
446
441
- void add (ElementT element , SettableApiFuture <ElementResultT > result , long throttledTimeMs ) {
447
+ void add (
448
+ ElementT element ,
449
+ BatchResource newResource ,
450
+ SettableApiFuture <ElementResultT > result ,
451
+ long throttledTimeMs ) {
442
452
builder .add (element );
443
453
entries .add (BatchEntry .create (element , result ));
444
- batchFlusher .add (element );
445
454
totalThrottledTimeMs += throttledTimeMs ;
455
+ resource = resource .add (newResource );
446
456
}
447
457
448
458
void onBatchSuccess (ResponseT response ) {
@@ -466,7 +476,7 @@ void onBatchFailure(Throwable throwable) {
466
476
}
467
477
468
478
boolean isEmpty () {
469
- return batchFlusher .isEmpty ();
479
+ return resource .isEmpty ();
470
480
}
471
481
}
472
482
0 commit comments