/** @return Nodes to execute on. */
  private Collection<ClusterNode> nodes() {
    CacheMode cacheMode = cctx.config().getCacheMode();

    switch (cacheMode) {
      case LOCAL:
        if (prj != null)
          U.warn(
              log,
              "Ignoring query projection because it's executed over LOCAL cache "
                  + "(only local node will be queried): "
                  + this);

        return Collections.singletonList(cctx.localNode());

      case REPLICATED:
        if (prj != null || partition() != null) return nodes(cctx, prj, partition());

        return cctx.affinityNode()
            ? Collections.singletonList(cctx.localNode())
            : Collections.singletonList(F.rand(nodes(cctx, null, partition())));

      case PARTITIONED:
        return nodes(cctx, prj, partition());

      default:
        throw new IllegalStateException("Unknown cache distribution mode: " + cacheMode);
    }
  }
  /** {@inheritDoc} */
  @Override
  protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
    IgniteConfiguration cfg = super.getConfiguration(gridName);

    cfg.setPeerClassLoadingEnabled(false);

    cfg.setDeploymentMode(depMode);

    if (initGar) {
      UriDeploymentSpi depSpi = new UriDeploymentSpi();

      depSpi.setUriList(Collections.singletonList(garFile));

      cfg.setDeploymentSpi(depSpi);
    }

    ((TcpDiscoverySpi) cfg.getDiscoverySpi()).setHeartbeatFrequency(500);

    return cfg;
  }