/** * Deallocate the record batch */ public void deallocate(ProducerBatch batch) { incomplete.remove(batch); // Only deallocate the batch if it is not a split batch because split batch are allocated outside the // buffer pool. if (!batch.isSplitBatch()) free.deallocate(batch.buffer(), batch.initialCapacity()); }
@Override public RecordMetadata get() throws InterruptedException, ExecutionException { this.result.await(); if (nextRecordMetadata != null) return nextRecordMetadata.get(); return valueOrError(); }
/** * Start closing the sender (won't actually complete until all data is sent out) */ public void initiateClose() { // Ensure accumulator is closed first to guarantee that no more appends are accepted after // breaking from the sender loop. Otherwise, we may miss some callbacks when shutting down. this.accumulator.close(); this.running = false; this.wakeup(); }
/** * We can retry a send if the error is transient and the number of attempts taken is fewer than the maximum allowed. * We can also retry OutOfOrderSequence exceptions for future batches, since if the first batch has failed, the * future batches are certain to fail with an OutOfOrderSequence exception. */ private boolean canRetry(ProducerBatch batch, ProduceResponse.PartitionResponse response, long now) { return !batch.hasReachedDeliveryTimeout(accumulator.getDeliveryTimeoutMs(), now) && batch.attempts() < this.retries && !batch.isDone() && ((response.error.exception() instanceof RetriableException) || (transactionManager != null && transactionManager.canRetry(response, batch))); }
private void reenqueueBatch(ProducerBatch batch, long currentTimeMs) { this.accumulator.reenqueue(batch, currentTimeMs); maybeRemoveFromInflightBatches(batch); this.sensors.recordRetries(batch.topicPartition.topic(), batch.recordCount); }
private boolean maybeTerminateRequestWithError(TxnRequestHandler requestHandler) { if (hasError()) { if (hasAbortableError() && requestHandler instanceof FindCoordinatorHandler) // No harm letting the FindCoordinator request go through if we're expecting to abort return false; requestHandler.fail(lastError); return true; } return false; }
void abortableError(RuntimeException e) { result.setError(e); transitionToAbortableError(e); result.done(); }
void fatalError(RuntimeException e) { result.setError(e); transitionToFatalError(e); result.done(); }
public synchronized TransactionalRequestResult beginCommit() { ensureTransactional(); maybeFailWithError(); transitionTo(State.COMMITTING_TRANSACTION); return beginCompletingTransaction(TransactionResult.COMMIT); }
void lookupCoordinator(TxnRequestHandler request) { lookupCoordinator(request.coordinatorType(), request.coordinatorKey()); }
/** * Package private for unit test. Get the buffer pool remaining size in bytes. */ long bufferPoolAvailableMemory() { return free.availableMemory(); }
/** * Closes the sender without sending out any pending messages. */ public void forceClose() { this.forceClose = true; initiateClose(); }
public synchronized void beginTransaction() { ensureTransactional(); maybeFailWithError(); transitionTo(State.IN_TRANSACTION); }
private FutureRecordMetadata futureRecordMetadata(ProduceRequestResult produceRequestResult) { return new FutureRecordMetadata( produceRequestResult, 0, RecordBatch.NO_TIMESTAMP, 0L, 0, 0, time ); }
synchronized void retry(TxnRequestHandler request) { request.setRetry(); enqueueRequest(request); }
/** * 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); }
@Override public int compare(ProducerBatch o1, ProducerBatch o2) { return o1.baseSequence() - o2.baseSequence(); } }));
/** * Check whether there are any pending batches (whether sent or unsent). */ public boolean hasIncomplete() { return !this.incomplete.isEmpty(); }
/** * Return `true` if {@link #done(long, long, RuntimeException)} has been invoked at least once, `false` otherwise. */ public boolean isDone() { return finalState() != null; }