protected void failUnsentRequests(Node node, RuntimeException e) {
   // clear unsent requests to node and fail their corresponding futures
   List<ClientRequest> unsentRequests = unsent.remove(node);
   if (unsentRequests != null) {
     for (ClientRequest request : unsentRequests) {
       RequestFutureCompletionHandler handler =
           (RequestFutureCompletionHandler) request.callback();
       handler.raise(e);
     }
   }
 }
 @Override
 public void onComplete(ClientResponse response) {
   if (response.wasDisconnected()) {
     ClientRequest request = response.request();
     RequestSend send = request.request();
     ApiKeys api = ApiKeys.forId(send.header().apiKey());
     int correlation = send.header().correlationId();
     log.debug(
         "Cancelled {} request {} with correlation id {} due to node {} being disconnected",
         api,
         request,
         correlation,
         send.destination());
     raise(DisconnectException.INSTANCE);
   } else {
     complete(response);
   }
 }
 private void failExpiredRequests(long now) {
   // clear all expired unsent requests and fail their corresponding futures
   Iterator<Map.Entry<Node, List<ClientRequest>>> iterator = unsent.entrySet().iterator();
   while (iterator.hasNext()) {
     Map.Entry<Node, List<ClientRequest>> requestEntry = iterator.next();
     Iterator<ClientRequest> requestIterator = requestEntry.getValue().iterator();
     while (requestIterator.hasNext()) {
       ClientRequest request = requestIterator.next();
       if (request.createdTimeMs() < now - unsentExpiryMs) {
         RequestFutureCompletionHandler handler =
             (RequestFutureCompletionHandler) request.callback();
         handler.raise(
             new TimeoutException("Failed to send request after " + unsentExpiryMs + " ms."));
         requestIterator.remove();
       } else break;
     }
     if (requestEntry.getValue().isEmpty()) iterator.remove();
   }
 }
 private void checkDisconnects(long now) {
   // any disconnects affecting requests that have already been transmitted will be handled
   // by NetworkClient, so we just need to check whether connections for any of the unsent
   // requests have been disconnected; if they have, then we complete the corresponding future
   // and set the disconnect flag in the ClientResponse
   Iterator<Map.Entry<Node, List<ClientRequest>>> iterator = unsent.entrySet().iterator();
   while (iterator.hasNext()) {
     Map.Entry<Node, List<ClientRequest>> requestEntry = iterator.next();
     Node node = requestEntry.getKey();
     if (client.connectionFailed(node)) {
       // Remove entry before invoking request callback to avoid callbacks handling
       // coordinator failures traversing the unsent list again.
       iterator.remove();
       for (ClientRequest request : requestEntry.getValue()) {
         RequestFutureCompletionHandler handler =
             (RequestFutureCompletionHandler) request.callback();
         handler.onComplete(new ClientResponse(request, now, true, null));
       }
     }
   }
 }