@Override public RecordMetadata get() throws InterruptedException, ExecutionException { this.result.await(); if (nextRecordMetadata != null) return nextRecordMetadata.get(); return valueOrError(); }
@Override public RecordMetadata get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { // Handle overflow. long now = time.milliseconds(); long timeoutMillis = unit.toMillis(timeout); long deadline = Long.MAX_VALUE - timeoutMillis < now ? Long.MAX_VALUE : now + timeoutMillis; boolean occurred = this.result.await(timeout, unit); if (!occurred) throw new TimeoutException("Timeout after waiting for " + timeoutMillis + " ms."); if (nextRecordMetadata != null) return nextRecordMetadata.get(deadline - time.milliseconds(), TimeUnit.MILLISECONDS); return valueOrError(); }
@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); }
/** * Test that an asynchronous request will eventually throw the right exception */ @Test(expected = ExecutionException.class) public void testError() throws Exception { FutureRecordMetadata future = new FutureRecordMetadata(asyncRequest(baseOffset, new CorruptRecordException(), 50L), relOffset, RecordBatch.NO_TIMESTAMP, 0L, 0, 0, Time.SYSTEM); future.get(); }
/** * Test that an asynchronous request will eventually return the right offset */ @Test public void testBlocking() throws Exception { FutureRecordMetadata future = new FutureRecordMetadata(asyncRequest(baseOffset, null, 50L), relOffset, RecordBatch.NO_TIMESTAMP, 0L, 0, 0, Time.SYSTEM); assertEquals(baseOffset + relOffset, future.get().offset()); }
/** * Test that waiting on a request that never completes times out */ @Test public void testTimeout() throws Exception { ProduceRequestResult request = new ProduceRequestResult(topicPartition); FutureRecordMetadata future = new FutureRecordMetadata(request, relOffset, RecordBatch.NO_TIMESTAMP, 0L, 0, 0, Time.SYSTEM); assertFalse("Request is not completed", future.isDone()); try { future.get(5, TimeUnit.MILLISECONDS); fail("Should have thrown exception."); } catch (TimeoutException e) { /* this is good */ } request.set(baseOffset, RecordBatch.NO_TIMESTAMP, null); request.done(); assertTrue(future.isDone()); assertEquals(baseOffset + relOffset, future.get().offset()); }
@Test public void testBatchCannotCompleteTwice() throws Exception { ProducerBatch batch = new ProducerBatch(new TopicPartition("topic", 1), memoryRecordsBuilder, now); MockCallback callback = new MockCallback(); FutureRecordMetadata future = batch.tryAppend(now, null, new byte[10], Record.EMPTY_HEADERS, callback, now); batch.done(500L, 10L, null); assertEquals(1, callback.invocations); assertNull(callback.exception); assertNotNull(callback.metadata); try { batch.done(1000L, 20L, null); fail("Expected exception from done"); } catch (IllegalStateException e) { // expected } RecordMetadata recordMetadata = future.get(); assertEquals(500L, recordMetadata.offset()); assertEquals(10L, recordMetadata.timestamp()); }
@Test public void testBatchCannotAbortTwice() throws Exception { ProducerBatch batch = new ProducerBatch(new TopicPartition("topic", 1), memoryRecordsBuilder, now); MockCallback callback = new MockCallback(); FutureRecordMetadata future = batch.tryAppend(now, null, new byte[10], Record.EMPTY_HEADERS, callback, now); KafkaException exception = new KafkaException(); batch.abort(exception); assertEquals(1, callback.invocations); assertEquals(exception, callback.exception); assertNull(callback.metadata); try { batch.abort(new KafkaException()); fail("Expected exception from abort"); } catch (IllegalStateException e) { // expected } assertEquals(1, callback.invocations); assertTrue(future.isDone()); try { future.get(); fail("Future should have thrown"); } catch (ExecutionException e) { assertEquals(exception, e.getCause()); } }
@Test public void testBatchAbort() throws Exception { ProducerBatch batch = new ProducerBatch(new TopicPartition("topic", 1), memoryRecordsBuilder, now); MockCallback callback = new MockCallback(); FutureRecordMetadata future = batch.tryAppend(now, null, new byte[10], Record.EMPTY_HEADERS, callback, now); KafkaException exception = new KafkaException(); batch.abort(exception); assertTrue(future.isDone()); assertEquals(1, callback.invocations); assertEquals(exception, callback.exception); assertNull(callback.metadata); // subsequent completion should be ignored assertFalse(batch.done(500L, 2342342341L, null)); assertFalse(batch.done(-1, -1, new KafkaException())); assertEquals(1, callback.invocations); assertTrue(future.isDone()); try { future.get(); fail("Future should have thrown"); } catch (ExecutionException e) { assertEquals(exception, e.getCause()); } }
assertNotNull(nextTransactionFuture.get());
assertNotNull(nextTransactionFuture.get());
/** * Complete the request * * @param baseOffset The base offset of the messages assigned by the server * @param exception The exception that occurred (or null if the request was successful) */ public void done(long baseOffset, RuntimeException exception) { this.produceFuture.done(topicPartition, baseOffset, exception); log.trace("Produced messages to topic-partition {} with base offset offset {} and error: {}.", topicPartition, baseOffset, exception); // execute callbacks for (int i = 0; i < this.thunks.size(); i++) { try { Thunk thunk = this.thunks.get(i); if (exception == null) thunk.callback.onCompletion(thunk.future.get(), null); else thunk.callback.onCompletion(null, exception); } catch (Exception e) { log.error("Error executing user-provided callback on message for topic-partition {}:", topicPartition, e); } } }