public static RequestBatchingTimestampService create(TimestampService untimedDelegate) { TimestampService delegate = TimingProxy.newProxyInstance(TimestampService.class, untimedDelegate, timer); DisruptorAutobatcher<Integer, TimestampRange> autobatcher = DisruptorAutobatcher.create(consumer(delegate)); return new RequestBatchingTimestampService(delegate, autobatcher); }
@Test public void delegatesInitializationCheck() { TimestampService delegate = mock(TimestampService.class); RequestBatchingTimestampService service = RequestBatchingTimestampService.create(delegate); when(delegate.isInitialized()) .thenReturn(false) .thenReturn(true); assertFalse(service.isInitialized()); assertTrue(service.isInitialized()); }
@VisibleForTesting static Consumer<List<BatchElement<Integer, TimestampRange>>> consumer(TimestampService delegate) { return batch -> { long totalTimestamps = batch.stream().mapToLong(BatchElement::argument).reduce(0, Math::addExact); long startInclusive = 0; long endExclusive = 0; for (BatchElement<Integer, TimestampRange> element : batch) { int timestampsRequired = element.argument(); if (element.argument() <= endExclusive - startInclusive) { element.result().set(createExclusiveRange(startInclusive, startInclusive + timestampsRequired)); startInclusive += timestampsRequired; totalTimestamps -= timestampsRequired; } else { TimestampRange requested = getFreshTimestampsFromDelegate( delegate, Ints.saturatedCast(totalTimestamps)); startInclusive = requested.getLowerBound(); endExclusive = Math.addExact(requested.getUpperBound(), 1); int toTake = Math.min(Ints.checkedCast(endExclusive - startInclusive), timestampsRequired); element.result().set(createExclusiveRange(startInclusive, startInclusive + toTake)); startInclusive += toTake; totalTimestamps -= timestampsRequired; } } }; }
@Before public void before() { timestamp = RequestBatchingTimestampService.create(unbatchedDelegate); }
private List<TimestampRange> requestBatches(int... sizes) { List<BatchElement<Integer, TimestampRange>> elements = Arrays.stream(sizes) .mapToObj(size -> ImmutableTestBatchElement.builder() .argument(size) .result(SettableFuture.create()) .build()) .collect(toList()); RequestBatchingTimestampService.consumer(unbatchedDelegate).accept(elements); return Futures.getUnchecked(Futures.allAsList(Lists.transform(elements, BatchElement::result))); }
@Override public long getFreshTimestamp() { TimestampRange range = getFreshTimestamps(1); return range.getLowerBound(); }
public static TimeLockClient createDefault(TimelockService timelockService) { AsyncTimeLockUnlocker asyncUnlocker = AsyncTimeLockUnlocker.create(timelockService); RequestBatchingTimestampService timestampService = RequestBatchingTimestampService.create(new TimelockServiceErrorDecorator(timelockService)); return new TimeLockClient( timelockService, timestampService, createLockRefresher(timelockService), asyncUnlocker); }
@Override public long getFreshTimestamp() { TimestampRange range = getFreshTimestamps(1); return range.getLowerBound(); }
public static RequestBatchingTimestampService create(TimestampService untimedDelegate) { TimestampService delegate = TimingProxy.newProxyInstance(TimestampService.class, untimedDelegate, timer); DisruptorAutobatcher<Integer, TimestampRange> autobatcher = DisruptorAutobatcher.create(consumer(delegate)); return new RequestBatchingTimestampService(delegate, autobatcher); }
@VisibleForTesting static Consumer<List<BatchElement<Integer, TimestampRange>>> consumer(TimestampService delegate) { return batch -> { long totalTimestamps = batch.stream().mapToLong(BatchElement::argument).reduce(0, Math::addExact); long startInclusive = 0; long endExclusive = 0; for (BatchElement<Integer, TimestampRange> element : batch) { int timestampsRequired = element.argument(); if (element.argument() <= endExclusive - startInclusive) { element.result().set(createExclusiveRange(startInclusive, startInclusive + timestampsRequired)); startInclusive += timestampsRequired; totalTimestamps -= timestampsRequired; } else { TimestampRange requested = getFreshTimestampsFromDelegate( delegate, Ints.saturatedCast(totalTimestamps)); startInclusive = requested.getLowerBound(); endExclusive = Math.addExact(requested.getUpperBound(), 1); int toTake = Math.min(Ints.checkedCast(endExclusive - startInclusive), timestampsRequired); element.result().set(createExclusiveRange(startInclusive, startInclusive + toTake)); startInclusive += toTake; totalTimestamps -= timestampsRequired; } } }; }
public static TimeLockClient createDefault(TimelockService timelockService) { AsyncTimeLockUnlocker asyncUnlocker = AsyncTimeLockUnlocker.create(timelockService); RequestBatchingTimestampService timestampService = RequestBatchingTimestampService.create(new TimelockServiceErrorDecorator(timelockService)); return new TimeLockClient( timelockService, timestampService, createLockRefresher(timelockService), asyncUnlocker); }