/**
   * Processes cache query response.
   *
   * @param sndId Sender node id.
   * @param res Query response.
   */
  @SuppressWarnings("unchecked")
  private void processQueryResponse(UUID sndId, GridCacheQueryResponse res) {
    if (log.isDebugEnabled()) log.debug("Received query response: " + res);

    GridCacheQueryFutureAdapter fut = getQueryFuture(res.requestId());

    if (fut != null)
      if (res.fields())
        ((GridCacheDistributedFieldsQueryFuture) fut)
            .onPage(
                sndId,
                res.metadata(),
                (Collection<Map<String, Object>>) ((Collection) res.data()),
                res.error(),
                res.isFinished());
      else fut.onPage(sndId, res.data(), res.error(), res.isFinished());
    else if (!cancelled.contains(res.requestId()))
      U.warn(
          log,
          "Received response for finished or unknown query [rmtNodeId="
              + sndId
              + ", res="
              + res
              + ']');
  }
  /** {@inheritDoc} */
  @Override
  void onCancelAtStop() {
    super.onCancelAtStop();

    for (GridCacheQueryFutureAdapter fut : futs.values())
      try {
        fut.cancel();
      } catch (IgniteCheckedException e) {
        U.error(log, "Failed to cancel running query future: " + fut, e);
      }

    U.interrupt(threads.values());
  }
  /** {@inheritDoc} */
  @Override
  void onWaitAtStop() {
    super.onWaitAtStop();

    // Wait till all requests will be finished.
    for (GridCacheQueryFutureAdapter fut : futs.values())
      try {
        fut.get();
      } catch (IgniteCheckedException e) {
        if (log.isDebugEnabled())
          log.debug(
              "Received query error while waiting for query to finish [queryFuture= "
                  + fut
                  + ", error= "
                  + e
                  + ']');
      }
  }
    private void init() {
      ClusterNode node = nodes.poll();

      GridCacheQueryFutureAdapter<?, ?, R> fut0 =
          (GridCacheQueryFutureAdapter<?, ?, R>)
              (node.isLocal()
                  ? qryMgr.queryLocal(bean)
                  : qryMgr.queryDistributed(bean, Collections.singleton(node)));

      fut0.listen(
          new IgniteInClosure<IgniteInternalFuture<Collection<R>>>() {
            @Override
            public void apply(IgniteInternalFuture<Collection<R>> fut) {
              try {
                onDone(fut.get());
              } catch (IgniteCheckedException e) {
                if (F.isEmpty(nodes)) onDone(e);
                else init();
              }
            }
          });

      fut = fut0;
    }
 /** {@inheritDoc} */
 @Override
 public R next() {
   return fut.next();
 }
 /** {@inheritDoc} */
 @Override
 public boolean cancel() throws IgniteCheckedException {
   return fut.cancel();
 }
 /** {@inheritDoc} */
 @Override
 public int available() {
   return fut.available();
 }