/** Initializes future. */
  @SuppressWarnings("ForLoopReplaceableByForEach")
  void finish() {
    if (tx.onNeedCheckBackup()) {
      assert tx.onePhaseCommit();

      checkBackup();

      // If checkBackup is set, it means that primary node has crashed and we will not need to send
      // finish request to it, so we can mark future as initialized.
      markInitialized();

      return;
    }

    try {
      if (tx.finish(commit) || (!commit && tx.state() == UNKNOWN)) {
        if ((tx.onePhaseCommit() && needFinishOnePhase())
            || (!tx.onePhaseCommit() && mappings != null)) {
          if (mappings.single()) {
            GridDistributedTxMapping mapping = mappings.singleMapping();

            if (mapping != null) finish(mapping);
          } else finish(mappings.mappings());
        }

        markInitialized();

        if (!isSync() && !isDone()) {
          boolean complete = true;

          synchronized (futs) {
            // Avoid collection copy and iterator creation.
            for (int i = 0; i < futs.size(); i++) {
              IgniteInternalFuture<IgniteInternalTx> f = futs.get(i);

              if (isMini(f) && !f.isDone()) {
                complete = false;

                break;
              }
            }
          }

          if (complete) onComplete();
        }
      } else onDone(new IgniteCheckedException("Failed to commit transaction: " + CU.txString(tx)));
    } catch (Error | RuntimeException e) {
      onDone(e);

      throw e;
    } catch (IgniteCheckedException e) {
      onDone(e);
    }
  }
Example #2
0
  /** {@inheritDoc} */
  @Override
  public IgniteInternalFuture<IgniteInternalTx> rollbackAsync() {
    if (log.isDebugEnabled()) log.debug("Rolling back near tx: " + this);

    GridNearTxFinishFuture fut = rollbackFut.get();

    if (fut != null) return fut;

    if (!rollbackFut.compareAndSet(null, fut = new GridNearTxFinishFuture<>(cctx, this, false)))
      return rollbackFut.get();

    cctx.mvcc().addFuture(fut, fut.futureId());

    IgniteInternalFuture<?> prepFut = this.prepFut.get();

    if (prepFut == null || prepFut.isDone()) {
      try {
        // Check for errors in prepare future.
        if (prepFut != null) prepFut.get();
      } catch (IgniteCheckedException e) {
        if (log.isDebugEnabled())
          log.debug("Got optimistic tx failure [tx=" + this + ", err=" + e + ']');
      }

      fut.finish();
    } else {
      prepFut.listen(
          new CI1<IgniteInternalFuture<?>>() {
            @Override
            public void apply(IgniteInternalFuture<?> f) {
              try {
                // Check for errors in prepare future.
                f.get();
              } catch (IgniteCheckedException e) {
                if (log.isDebugEnabled())
                  log.debug("Got optimistic tx failure [tx=" + this + ", err=" + e + ']');
              }

              GridNearTxFinishFuture fut0 = rollbackFut.get();

              fut0.finish();
            }
          });
    }

    return fut;
  }
Example #3
0
  /**
   * Rolls back local part of colocated transaction.
   *
   * @return Commit future.
   */
  public IgniteInternalFuture<IgniteInternalTx> rollbackAsyncLocal() {
    if (log.isDebugEnabled()) log.debug("Rolling back colocated tx locally: " + this);

    final GridDhtTxFinishFuture fut = new GridDhtTxFinishFuture<>(cctx, this, /*commit*/ false);

    cctx.mvcc().addFuture(fut, fut.futureId());

    IgniteInternalFuture<?> prep = prepFut.get();

    if (prep == null || prep.isDone()) {
      try {
        if (prep != null) prep.get();
      } catch (IgniteCheckedException e) {
        if (log.isDebugEnabled())
          log.debug(
              "Failed to prepare transaction during rollback (will ignore) [tx="
                  + this
                  + ", msg="
                  + e.getMessage()
                  + ']');
      }

      fut.finish();
    } else
      prep.listen(
          new CI1<IgniteInternalFuture<?>>() {
            @Override
            public void apply(IgniteInternalFuture<?> f) {
              try {
                f.get(); // Check for errors of a parent future.
              } catch (IgniteCheckedException e) {
                log.debug(
                    "Failed to prepare transaction during rollback (will ignore) [tx="
                        + this
                        + ", msg="
                        + e.getMessage()
                        + ']');
              }

              fut.finish();
            }
          });

    return fut;
  }
Example #4
0
  /**
   * Commits local part of colocated transaction.
   *
   * @return Commit future.
   */
  public IgniteInternalFuture<IgniteInternalTx> commitAsyncLocal() {
    if (log.isDebugEnabled()) log.debug("Committing colocated tx locally: " + this);

    // In optimistic mode prepare was called explicitly.
    if (pessimistic()) prepareAsync();

    IgniteInternalFuture<?> prep = prepFut.get();

    // Do not create finish future if there are no remote nodes.
    if (F.isEmpty(dhtMap) && F.isEmpty(nearMap)) {
      if (prep != null) return (IgniteInternalFuture<IgniteInternalTx>) (IgniteInternalFuture) prep;

      return new GridFinishedFuture<IgniteInternalTx>(this);
    }

    final GridDhtTxFinishFuture fut = new GridDhtTxFinishFuture<>(cctx, this, /*commit*/ true);

    cctx.mvcc().addFuture(fut, fut.futureId());

    if (prep == null || prep.isDone()) {
      assert prep != null || optimistic();

      try {
        if (prep != null) prep.get(); // Check for errors of a parent future.

        fut.finish();
      } catch (IgniteTxOptimisticCheckedException e) {
        if (log.isDebugEnabled())
          log.debug("Failed optimistically to prepare transaction [tx=" + this + ", e=" + e + ']');

        fut.onError(e);
      } catch (IgniteCheckedException e) {
        U.error(log, "Failed to prepare transaction: " + this, e);

        fut.onError(e);
      }
    } else
      prep.listen(
          new CI1<IgniteInternalFuture<?>>() {
            @Override
            public void apply(IgniteInternalFuture<?> f) {
              try {
                f.get(); // Check for errors of a parent future.

                fut.finish();
              } catch (IgniteTxOptimisticCheckedException e) {
                if (log.isDebugEnabled())
                  log.debug(
                      "Failed optimistically to prepare transaction [tx="
                          + this
                          + ", e="
                          + e
                          + ']');

                fut.onError(e);
              } catch (IgniteCheckedException e) {
                U.error(log, "Failed to prepare transaction: " + this, e);

                fut.onError(e);
              }
            }
          });

    return fut;
  }
  /** @throws Exception If failed. */
  private void testReentrantLockMultinode1(final boolean fair) throws Exception {
    if (gridCount() == 1) return;

    IgniteLock lock = grid(0).reentrantLock("s1", true, fair, true);

    List<IgniteInternalFuture<?>> futs = new ArrayList<>();

    for (int i = 0; i < gridCount(); i++) {
      final Ignite ignite = grid(i);

      futs.add(
          GridTestUtils.runAsync(
              new Callable<Void>() {
                @Override
                public Void call() throws Exception {
                  IgniteLock lock = ignite.reentrantLock("s1", true, fair, false);

                  assertNotNull(lock);

                  IgniteCondition cond1 = lock.getOrCreateCondition("c1");

                  IgniteCondition cond2 = lock.getOrCreateCondition("c2");

                  try {
                    boolean wait = lock.tryLock(30_000, MILLISECONDS);

                    assertTrue(wait);

                    cond2.signal();

                    cond1.await();
                  } finally {
                    lock.unlock();
                  }

                  return null;
                }
              }));
    }

    boolean done = false;

    while (!done) {
      done = true;

      for (IgniteInternalFuture<?> fut : futs) {
        if (!fut.isDone()) done = false;
      }

      try {
        lock.lock();

        lock.getOrCreateCondition("c1").signal();

        lock.getOrCreateCondition("c2").await(10, MILLISECONDS);
      } finally {
        lock.unlock();
      }
    }

    for (IgniteInternalFuture<?> fut : futs) fut.get(30_000);
  }
Example #6
0
    /** {@inheritDoc} */
    @Override
    protected void body() throws InterruptedException, IgniteInterruptedCheckedException {
      try {
        IgfsDataInputStream dis = new IgfsDataInputStream(endpoint.inputStream());

        byte[] hdr = new byte[IgfsMarshaller.HEADER_SIZE];

        boolean first = true;

        while (!Thread.currentThread().isInterrupted()) {
          dis.readFully(hdr);

          final long reqId = U.bytesToLong(hdr, 0);

          int ordinal = U.bytesToInt(hdr, 8);

          if (first) { // First message must be HANDSHAKE.
            if (reqId != 0 || ordinal != IgfsIpcCommand.HANDSHAKE.ordinal()) {
              if (log.isDebugEnabled())
                log.debug(
                    "IGFS IPC handshake failed [reqId=" + reqId + ", ordinal=" + ordinal + ']');

              return;
            }

            first = false;
          }

          final IgfsIpcCommand cmd = IgfsIpcCommand.valueOf(ordinal);

          IgfsMessage msg = marsh.unmarshall(cmd, hdr, dis);

          IgniteInternalFuture<IgfsMessage> fut = hnd.handleAsync(ses, msg, dis);

          // If fut is null, no response is required.
          if (fut != null) {
            if (fut.isDone()) {
              IgfsMessage res;

              try {
                res = fut.get();
              } catch (IgniteCheckedException e) {
                res = new IgfsControlResponse();

                ((IgfsControlResponse) res).error(e);
              }

              try {
                synchronized (out) {
                  // Reuse header.
                  IgfsMarshaller.fillHeader(hdr, reqId, res.command());

                  marsh.marshall(res, hdr, out);

                  out.flush();
                }
              } catch (IOException | IgniteCheckedException e) {
                shutdown0(e);
              }
            } else {
              fut.listen(
                  new CIX1<IgniteInternalFuture<IgfsMessage>>() {
                    @Override
                    public void applyx(IgniteInternalFuture<IgfsMessage> fut) {
                      IgfsMessage res;

                      try {
                        res = fut.get();
                      } catch (IgniteCheckedException e) {
                        res = new IgfsControlResponse();

                        ((IgfsControlResponse) res).error(e);
                      }

                      try {
                        synchronized (out) {
                          byte[] hdr = IgfsMarshaller.createHeader(reqId, res.command());

                          marsh.marshall(res, hdr, out);

                          out.flush();
                        }
                      } catch (IOException | IgniteCheckedException e) {
                        shutdown0(e);
                      }
                    }
                  });
            }
          }
        }
      } catch (EOFException ignored) {
        // Client closed connection.
      } catch (IgniteCheckedException | IOException e) {
        if (!isCancelled())
          U.error(log, "Failed to read data from client (will close connection)", e);
      } finally {
        onFinished();
      }
    }