@Test public void testBatching() throws Exception { AccumulatingBatchReceiver<SimpleBatch> receiver = new AccumulatingBatchReceiver<>(ApiFutures.<Void>immediateFuture(null)); ThresholdBatcher<SimpleBatch> batcher = createSimpleBatcherBuidler(receiver) .setThresholds(BatchingThresholds.<SimpleBatch>create(2)) .build(); batcher.add(SimpleBatch.fromInteger(3)); batcher.add(SimpleBatch.fromInteger(5)); // Give time for the executor to push the batch Thread.sleep(100); assertThat(receiver.getBatches()).hasSize(1); batcher.add(SimpleBatch.fromInteger(7)); batcher.add(SimpleBatch.fromInteger(9)); // Give time for the executor to push the batch Thread.sleep(100); assertThat(receiver.getBatches()).hasSize(2); batcher.add(SimpleBatch.fromInteger(11)); batcher.pushCurrentBatch().get(); List<List<Integer>> expected = Arrays.asList(Arrays.asList(3, 5), Arrays.asList(7, 9), Arrays.asList(11)); List<List<Integer>> actual = new ArrayList<>(); for (SimpleBatch batch : receiver.getBatches()) { actual.add(batch.getIntegers()); } assertThat(actual).isEqualTo(expected); }
@Test public void testBatchingWithDelay() throws Exception { AccumulatingBatchReceiver<SimpleBatch> receiver = new AccumulatingBatchReceiver<>(ApiFutures.<Void>immediateFuture(null)); ThresholdBatcher<SimpleBatch> batcher = createSimpleBatcherBuidler(receiver).setMaxDelay(Duration.ofMillis(100)).build(); batcher.add(SimpleBatch.fromInteger(3)); batcher.add(SimpleBatch.fromInteger(5)); // Give time for the delay to trigger and push the batch Thread.sleep(500); assertThat(receiver.getBatches()).hasSize(1); batcher.add(SimpleBatch.fromInteger(11)); batcher.pushCurrentBatch().get(); List<List<Integer>> expected = Arrays.asList(Arrays.asList(3, 5), Arrays.asList(11)); List<List<Integer>> actual = new ArrayList<>(); for (SimpleBatch batch : receiver.getBatches()) { actual.add(batch.getIntegers()); } assertThat(actual).isEqualTo(expected); }
@Test public void testAdd() throws Exception { AccumulatingBatchReceiver<SimpleBatch> receiver = new AccumulatingBatchReceiver<>(ApiFutures.<Void>immediateFuture(null)); ThresholdBatcher<SimpleBatch> batcher = createSimpleBatcherBuidler(receiver).build(); batcher.add(SimpleBatch.fromInteger(14)); assertThat(batcher.isEmpty()).isFalse(); assertThat(receiver.getBatches()).hasSize(0); batcher.pushCurrentBatch().get(); assertThat(batcher.isEmpty()).isTrue(); assertThat(receiver.getBatches()).hasSize(1); assertThat(receiver.getBatches().get(0).getIntegers()).isEqualTo(Arrays.asList(14)); }
@Override public ApiFuture<ResponseT> futureCall(RequestT request, ApiCallContext context) { if (batcherFactory.getBatchingSettings().getIsEnabled()) { BatchedFuture<ResponseT> result = BatchedFuture.<ResponseT>create(); UnaryCallable<RequestT, ResponseT> unaryCallable = callable.withDefaultCallContext(context); Batch<RequestT, ResponseT> batchableMessage = new Batch<RequestT, ResponseT>(batchingDescriptor, request, unaryCallable, result); PartitionKey partitionKey = batchingDescriptor.getBatchPartitionKey(request); ThresholdBatcher<Batch<RequestT, ResponseT>> batcher = batcherFactory.getPushingBatcher(partitionKey); try { batcher.add(batchableMessage); return result; } catch (FlowControlException e) { throw FlowControlRuntimeException.fromFlowControlException(e); } } else { return callable.futureCall(request, context); } } }
assertThat(trackedFlowController.getBytesReleased()).isEqualTo(0); batcher.add(SimpleBatch.fromInteger(3)); batcher.add(SimpleBatch.fromInteger(5)); batcher.add(SimpleBatch.fromInteger(7)); try { batcher.add(SimpleBatch.fromInteger(9)); Assert.fail("expected exception"); } catch (FlowControlException e) { batcher.add(SimpleBatch.fromInteger(11)); batcher.add(SimpleBatch.fromInteger(13)); batcher.pushCurrentBatch().get();
assertThat(trackedFlowController.getBytesReleased()).isEqualTo(0); batcher.add(SimpleBatch.fromInteger(3)); batcher.add(SimpleBatch.fromInteger(5)); batcher.add( SimpleBatch.fromInteger(7)); // We expect to block here until the first batch is handled assertThat(receiver.getBatches()).hasSize(1); batcher.add(SimpleBatch.fromInteger(9)); batcher.add( SimpleBatch.fromInteger(11)); // We expect to block here until the second batch is handled assertThat(receiver.getBatches()).hasSize(2);
@Override public ApiFuture<ResponseT> futureCall(RequestT request, ApiCallContext context) { if (batcherFactory.getBatchingSettings().getIsEnabled()) { BatchedFuture<ResponseT> result = BatchedFuture.<ResponseT>create(); UnaryCallable<RequestT, ResponseT> unaryCallable = callable.withDefaultCallContext(context); Batch<RequestT, ResponseT> batchableMessage = new Batch<RequestT, ResponseT>(batchingDescriptor, request, unaryCallable, result); PartitionKey partitionKey = batchingDescriptor.getBatchPartitionKey(request); ThresholdBatcher<Batch<RequestT, ResponseT>> batcher = batcherFactory.getPushingBatcher(partitionKey); try { batcher.add(batchableMessage); return result; } catch (FlowControlException e) { throw FlowControlRuntimeException.fromFlowControlException(e); } } else { return callable.futureCall(request, context); } } }
assertThat(trackedFlowController.getBytesReleased()).isEqualTo(0); batcher.add(SimpleBatch.fromInteger(3)); try { batcher.pushCurrentBatch().get();