Search in sources :

Example 1 with ConnectionState

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));
    }
}
Also used : ConnectionState(org.apache.kafka.raft.RequestManager.ConnectionState)

Example 2 with ConnectionState

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);
}
Also used : ApiKeys(org.apache.kafka.common.protocol.ApiKeys) Errors(org.apache.kafka.common.protocol.Errors) ApiMessage(org.apache.kafka.common.protocol.ApiMessage) ConnectionState(org.apache.kafka.raft.RequestManager.ConnectionState)

Example 3 with ConnectionState

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);
    }
}
Also used : ApiKeys(org.apache.kafka.common.protocol.ApiKeys) ConnectionState(org.apache.kafka.raft.RequestManager.ConnectionState)

Aggregations

ConnectionState (org.apache.kafka.raft.RequestManager.ConnectionState)3 ApiKeys (org.apache.kafka.common.protocol.ApiKeys)2 ApiMessage (org.apache.kafka.common.protocol.ApiMessage)1 Errors (org.apache.kafka.common.protocol.Errors)1