/** * This method is used when we have to split a large batch in smaller ones. A chained metadata will allow the * future that has already returned to the users to wait on the newly created split batches even after the * old big batch has been deemed as done. */ void chain(FutureRecordMetadata futureRecordMetadata) { if (nextRecordMetadata == null) nextRecordMetadata = futureRecordMetadata; else nextRecordMetadata.chain(futureRecordMetadata); }
/** * This method is only used by {@link #split(int)} when splitting a large batch to smaller ones. * @return true if the record has been successfully appended, false otherwise. */ private boolean tryAppendForSplit(long timestamp, ByteBuffer key, ByteBuffer value, Header[] headers, Thunk thunk) { if (!recordsBuilder.hasRoomFor(timestamp, key, value, headers)) { return false; } else { // No need to get the CRC. this.recordsBuilder.append(timestamp, key, value, headers); this.maxRecordSize = Math.max(this.maxRecordSize, AbstractRecords.estimateSizeInBytesUpperBound(magic(), recordsBuilder.compressionType(), key, value, headers)); FutureRecordMetadata future = new FutureRecordMetadata(this.produceFuture, this.recordCount, timestamp, thunk.future.checksumOrNull(), key == null ? -1 : key.remaining(), value == null ? -1 : value.remaining(), Time.SYSTEM); // Chain the future to the original thunk. thunk.future.chain(future); this.thunks.add(thunk); this.recordCount++; return true; } }
@Test public void testFutureGetWithSeconds() throws ExecutionException, InterruptedException, TimeoutException { ProduceRequestResult produceRequestResult = mockProduceRequestResult(); FutureRecordMetadata future = futureRecordMetadata(produceRequestResult); ProduceRequestResult chainedProduceRequestResult = mockProduceRequestResult(); future.chain(futureRecordMetadata(chainedProduceRequestResult)); future.get(1L, TimeUnit.SECONDS); verify(produceRequestResult).await(1L, TimeUnit.SECONDS); verify(chainedProduceRequestResult).await(1000L, TimeUnit.MILLISECONDS); }
@Test public void testFutureGetWithMilliSeconds() throws ExecutionException, InterruptedException, TimeoutException { ProduceRequestResult produceRequestResult = mockProduceRequestResult(); FutureRecordMetadata future = futureRecordMetadata(produceRequestResult); ProduceRequestResult chainedProduceRequestResult = mockProduceRequestResult(); future.chain(futureRecordMetadata(chainedProduceRequestResult)); future.get(1000L, TimeUnit.MILLISECONDS); verify(produceRequestResult).await(1000L, TimeUnit.MILLISECONDS); verify(chainedProduceRequestResult).await(1000L, TimeUnit.MILLISECONDS); }