/** {@inheritDoc} */
  @Override
  public void start0() throws IgniteCheckedException {
    super.start0();

    assert cctx.config().getCacheMode() != LOCAL;

    cctx.io()
        .addHandler(
            cctx.cacheId(),
            GridCacheQueryRequest.class,
            new CI2<UUID, GridCacheQueryRequest>() {
              @Override
              public void apply(UUID nodeId, GridCacheQueryRequest req) {
                processQueryRequest(nodeId, req);
              }
            });

    lsnr =
        new GridLocalEventListener() {
          @Override
          public void onEvent(Event evt) {
            DiscoveryEvent discoEvt = (DiscoveryEvent) evt;

            for (GridCacheDistributedQueryFuture fut : futs.values())
              fut.onNodeLeft(discoEvt.eventNode().id());
          }
        };

    cctx.events().addListener(lsnr, EVT_NODE_LEFT, EVT_NODE_FAILED);
  }
  /** {@inheritDoc} */
  @Override
  public void printMemoryStats() {
    super.printMemoryStats();

    X.println(">>>   threadsSize: " + threads.size());
    X.println(">>>   futsSize: " + futs.size());
  }
  /** {@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
                  + ']');
      }
  }
  /** {@inheritDoc} */
  @Override
  protected void onKernalStop0(boolean cancel) {
    super.onKernalStop0(cancel);

    cctx.events().removeListener(lsnr);
  }