/** @throws Exception If failed. */
  @SuppressWarnings("unchecked")
  public void testCancel() throws Exception {
    Grid grid = G.grid(getTestGridName());

    grid.compute()
        .localDeployTask(GridCancelTestTask.class, U.detectClassLoader(GridCancelTestTask.class));

    GridComputeTaskFuture<?> fut = grid.compute().execute(GridCancelTestTask.class.getName(), null);

    // Wait until jobs begin execution.
    boolean await = startSignal.await(WAIT_TIME, TimeUnit.MILLISECONDS);

    assert await : "Jobs did not start.";

    info("Test task result: " + fut);

    assert fut != null;

    // Only first job should successfully complete.
    Object res = fut.get();
    assert (Integer) res == 1;

    // Wait for all jobs to finish.
    await = stopSignal.await(WAIT_TIME, TimeUnit.MILLISECONDS);
    assert await : "Jobs did not stop.";

    // One is definitely processed. But there might be some more processed or cancelled or processed
    // and cancelled.
    // Thus total number should be at least SPLIT_COUNT and at most (SPLIT_COUNT - 1) *2 +1
    assert (cancelCnt + processedCnt) >= SPLIT_COUNT
            && (cancelCnt + processedCnt) <= (SPLIT_COUNT - 1) * 2 + 1
        : "Invalid cancel count value: " + cancelCnt;
  }
    /**
     * Send message optionally either blocking it or throwing an exception if it is of {@link
     * GridJobExecuteResponse} type.
     *
     * @param node Destination node.
     * @param msg Message to be sent.
     * @throws GridSpiException If failed.
     */
    private void sendMessage0(GridNode node, GridTcpCommunicationMessageAdapter msg)
        throws GridSpiException {
      if (msg instanceof GridIoMessage) {
        GridIoMessage msg0 = (GridIoMessage) msg;

        if (msg0.message() instanceof GridJobExecuteResponse) {
          respLatch.countDown();

          if (wait) {
            try {
              U.await(waitLatch);
            } catch (GridInterruptedException ignore) {
              // No-op.
            }
          }
        }
      }

      if (!block) super.sendMessage(node, msg);
    }
  /**
   * Test how IPC cache map works.
   *
   * @throws Exception If failed.
   */
  @SuppressWarnings("unchecked")
  public void testIpcCache() throws Exception {
    Field cacheField = GridGgfsHadoopIpcIo.class.getDeclaredField("ipcCache");

    cacheField.setAccessible(true);

    Field activeCntField = GridGgfsHadoopIpcIo.class.getDeclaredField("activeCnt");

    activeCntField.setAccessible(true);

    Map<String, GridGgfsHadoopIpcIo> cache =
        (Map<String, GridGgfsHadoopIpcIo>) cacheField.get(null);

    String name = "ggfs:" + getTestGridName(0) + "@";

    Configuration cfg = new Configuration();

    cfg.addResource(U.resolveGridGainUrl(HADOOP_FS_CFG));
    cfg.setBoolean("fs.ggfs.impl.disable.cache", true);
    cfg.setBoolean(String.format(GridGgfsHadoopUtils.PARAM_GGFS_ENDPOINT_NO_EMBED, name), true);

    // Ensure that existing IO is reused.
    FileSystem fs1 = FileSystem.get(new URI("ggfs://" + name + "/"), cfg);

    assertEquals(1, cache.size());

    GridGgfsHadoopIpcIo io = null;

    System.out.println("CACHE: " + cache);

    for (String key : cache.keySet()) {
      if (key.contains("10500")) {
        io = cache.get(key);

        break;
      }
    }

    assert io != null;

    assertEquals(1, ((AtomicInteger) activeCntField.get(io)).get());

    // Ensure that when IO is used by multiple file systems and one of them is closed, IO is not
    // stopped.
    FileSystem fs2 = FileSystem.get(new URI("ggfs://" + name + "/abc"), cfg);

    assertEquals(1, cache.size());
    assertEquals(2, ((AtomicInteger) activeCntField.get(io)).get());

    fs2.close();

    assertEquals(1, cache.size());
    assertEquals(1, ((AtomicInteger) activeCntField.get(io)).get());

    Field stopField = GridGgfsHadoopIpcIo.class.getDeclaredField("stopping");

    stopField.setAccessible(true);

    assert !(Boolean) stopField.get(io);

    // Ensure that IO is stopped when nobody else is need it.
    fs1.close();

    assert cache.isEmpty();

    assert (Boolean) stopField.get(io);
  }
 /**
  * Await for job execution response to come.
  *
  * @throws GridInterruptedException If interrupted.
  */
 private void awaitResponse() throws GridInterruptedException {
   U.await(respLatch);
 }
  /** {@inheritDoc} */
  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    super.readExternal(in);

    failedNodesIds = U.readList(in);
  }
  /** {@inheritDoc} */
  @Override
  public void writeExternal(ObjectOutput out) throws IOException {
    super.writeExternal(out);

    U.writeCollection(out, failedNodesIds);
  }