use of org.apache.kafka.raft.RequestManager.ConnectionState in project kafka by apache.
the class KafkaRaftClient method pollFollowerAsObserver.
private long pollFollowerAsObserver(FollowerState state, long currentTimeMs) {
if (state.hasFetchTimeoutExpired(currentTimeMs)) {
return maybeSendAnyVoterFetch(currentTimeMs);
} else {
final long backoffMs;
// If the current leader is backing off due to some failure or if the
// request has timed out, then we attempt to send the Fetch to another
// voter in order to discover if there has been a leader change.
ConnectionState connection = requestManager.getOrCreate(state.leaderId());
if (connection.hasRequestTimedOut(currentTimeMs)) {
backoffMs = maybeSendAnyVoterFetch(currentTimeMs);
connection.reset();
} else if (connection.isBackingOff(currentTimeMs)) {
backoffMs = maybeSendAnyVoterFetch(currentTimeMs);
} else {
backoffMs = maybeSendFetchOrFetchSnapshot(state, currentTimeMs);
}
return Math.min(backoffMs, state.remainingFetchTimeMs(currentTimeMs));
}
}
use of org.apache.kafka.raft.RequestManager.ConnectionState in project kafka by apache.
the class KafkaRaftClient method maybeSendRequest.
/**
* Attempt to send a request. Return the time to wait before the request can be retried.
*/
private long maybeSendRequest(long currentTimeMs, int destinationId, Supplier<ApiMessage> requestSupplier) {
ConnectionState connection = requestManager.getOrCreate(destinationId);
if (connection.isBackingOff(currentTimeMs)) {
long remainingBackoffMs = connection.remainingBackoffMs(currentTimeMs);
logger.debug("Connection for {} is backing off for {} ms", destinationId, remainingBackoffMs);
return remainingBackoffMs;
}
if (connection.isReady(currentTimeMs)) {
int correlationId = channel.newCorrelationId();
ApiMessage request = requestSupplier.get();
RaftRequest.Outbound requestMessage = new RaftRequest.Outbound(correlationId, request, destinationId, currentTimeMs);
requestMessage.completion.whenComplete((response, exception) -> {
if (exception != null) {
ApiKeys api = ApiKeys.forId(request.apiKey());
Errors error = Errors.forException(exception);
ApiMessage errorResponse = RaftUtil.errorResponse(api, error);
response = new RaftResponse.Inbound(correlationId, errorResponse, destinationId);
}
messageQueue.add(response);
});
channel.send(requestMessage);
logger.trace("Sent outbound request: {}", requestMessage);
connection.onRequestSent(correlationId, currentTimeMs);
return Long.MAX_VALUE;
}
return connection.remainingRequestTimeMs(currentTimeMs);
}
use of org.apache.kafka.raft.RequestManager.ConnectionState in project kafka by apache.
the class KafkaRaftClient method handleResponse.
private void handleResponse(RaftResponse.Inbound response, long currentTimeMs) {
// The response epoch matches the local epoch, so we can handle the response
ApiKeys apiKey = ApiKeys.forId(response.data.apiKey());
final boolean handledSuccessfully;
switch(apiKey) {
case FETCH:
handledSuccessfully = handleFetchResponse(response, currentTimeMs);
break;
case VOTE:
handledSuccessfully = handleVoteResponse(response, currentTimeMs);
break;
case BEGIN_QUORUM_EPOCH:
handledSuccessfully = handleBeginQuorumEpochResponse(response, currentTimeMs);
break;
case END_QUORUM_EPOCH:
handledSuccessfully = handleEndQuorumEpochResponse(response, currentTimeMs);
break;
case FETCH_SNAPSHOT:
handledSuccessfully = handleFetchSnapshotResponse(response, currentTimeMs);
break;
default:
throw new IllegalArgumentException("Received unexpected response type: " + apiKey);
}
ConnectionState connection = requestManager.getOrCreate(response.sourceId());
if (handledSuccessfully) {
connection.onResponseReceived(response.correlationId);
} else {
connection.onResponseError(response.correlationId, currentTimeMs);
}
}
Aggregations