/** {@inheritDoc} */
    @Override
    public Serializable execute() {
      synchronized (mux) {
        execCnt++;
      }

      if (log.isInfoEnabled()) log.info("Executing job: " + jobCtx.getJobId());

      long now = System.currentTimeMillis();

      while (!isCancelled && now < thresholdTime) {
        synchronized (mux) {
          try {
            mux.wait(thresholdTime - now);
          } catch (InterruptedException ignored) {
            // No-op.
          }
        }

        now = System.currentTimeMillis();
      }

      synchronized (mux) {
        return isCancelled ? 1 : 0;
      }
    }
    /** {@inheritDoc} */
    @Override
    public void spiStart(String gridName) throws IgniteSpiException {
      // Start SPI start stopwatch.
      startStopwatch();

      // Ack start.
      if (log.isInfoEnabled()) log.info(startInfo());
    }
    /** {@inheritDoc} */
    @Override
    public Collection<? extends ComputeJob> split(int gridSize, Serializable arg) {
      if (log.isInfoEnabled())
        log.info("Splitting task [task=" + this + ", gridSize=" + gridSize + ", arg=" + arg + ']');

      Collection<GridCancelTestJob> jobs = new ArrayList<>(SPLIT_COUNT);

      for (int i = 0; i < SPLIT_COUNT; i++) jobs.add(new GridCancelTestJob());

      return jobs;
    }
    /** {@inheritDoc} */
    @Override
    public Object reduce(List<ComputeJobResult> results) {
      if (log.isInfoEnabled())
        log.info("Aggregating job [job=" + this + ", results=" + results + ']');

      int res = 0;

      for (ComputeJobResult result : results) {
        assert result != null;

        if (result.getData() != null) res += (Integer) result.getData();
      }

      return res;
    }
    /** {@inheritDoc} */
    @Override
    public void cancel() {
      synchronized (mux) {
        isCancelled = true;

        cancelCnt++;

        mux.notifyAll();
      }

      log.warning("Job cancelled: " + jobCtx.getJobId());
    }
  /** {@inheritDoc} */
  @Override
  protected Object executeJob(int gridSize, String type) {
    log.info(">>> Starting new grid node [currGridSize=" + gridSize + ", arg=" + type + "]");

    if (type == null) throw new IllegalArgumentException("Node type to start should be specified.");

    IgniteConfiguration cfg = getConfig(type);

    // Generate unique for this VM grid name.
    String gridName = cfg.getGridName() + " (" + UUID.randomUUID() + ")";

    // Update grid name (required to be unique).
    cfg.setGridName(gridName);

    // Start new node in current VM.
    Ignite g = G.start(cfg);

    log.info(
        ">>> Grid started [nodeId=" + g.cluster().localNode().id() + ", name='" + g.name() + "']");

    return true;
  }
 /** {@inheritDoc} */
 @Override
 public void spiStop() throws IgniteSpiException {
   // Ack stop.
   if (log.isInfoEnabled()) log.info(stopInfo());
 }