之前我们分析的都是消息正常发出和收到响应,现在分析一下对应异常消息的处理
Producer对请求超市的处理
在Sender的run方法中,有专门检测超时的请求
public class Sender implements Runnable {
void run(long now) {
/**
* 建立网络连接,发送数据
*/
client.poll(pollTimeout, now);
}
}
public List<ClientResponse> poll(long timeout, long now) {
/**
* 处理超时的请求
*/
handleTimedOutRequests(responses, updatedNow);
return responses;
}
private void handleTimedOutRequests(List<ClientResponse> responses, long now) {
/**
* 获取到超时的node
*/
List<String> nodeIds = this.inFlightRequests.nodesWithTimedOutRequests(now);
for (String nodeId : nodeIds) {
// close connection to the node
this.selector.close(nodeId);
log.debug("Disconnecting from node {} due to request timeout.", nodeId);
/**
*超时请求的处理
**/
processDisconnection(responses, nodeId, now, ChannelState.LOCAL_CLOSE);
}
// we disconnected, so we should probably refresh our metadata
if (!nodeIds.isEmpty())
metadataUpdater.requestUpdate();
}
判断超时
public List<String> nodesWithTimedOutRequests(long now) {
List<String> nodeIds = new ArrayList<>();
for (Map.Entry<String, Deque<NetworkClient.InFlightRequest>> requestEntry : requests.entrySet()) {
String nodeId = requestEntry.getKey();
Deque<NetworkClient.InFlightRequest> deque = requestEntry.getValue();
//判断是否超时
if (hasExpiredRequest(now, deque))
nodeIds.add(nodeId);
}
return nodeIds;
}
private Boolean hasExpiredRequest(long now, Deque<NetworkClient.InFlightRequest> deque) {
for (NetworkClient.InFlightRequest request : deque) {
long timeSinceSend = Math.max(0, now - request.sendTimeMs);
if (timeSinceSend > request.requestTimeoutMs)
return true;
}
return false;
}
可以看到,生产者判断请求超时是当前时间与请求的发送时间的差值与请求设置的超时时间作比较
对请求超时的处理
private void processDisconnection(List<ClientResponse> responses,
String nodeId,
long now,
ChannelState disconnectState) {
/**
* 修改连接状态
*/
connectionStates.disconnected(nodeId, now);
apiVersions.remove(nodeId);