/** @param m Mapping. */ @SuppressWarnings({"unchecked"}) private void finish(GridDistributedTxMapping<K, V> m) { GridRichNode n = m.node(); assert !m.empty(); GridNearTxFinishRequest req = new GridNearTxFinishRequest<K, V>( futId, tx.xidVersion(), tx.commitVersion(), tx.threadId(), commit, tx.isInvalidate(), m.explicitLock(), tx.topologyVersion(), null, null, null, commit && tx.pessimistic() ? m.writes() : null, tx.syncCommit() && commit || tx.syncRollback() && !commit); // If this is the primary node for the keys. if (n.isLocal()) { req.miniId(GridUuid.randomUuid()); if (CU.DHT_ENABLED) { GridFuture<GridCacheTx> fut = commit ? dht().commitTx(n.id(), req) : dht().rollbackTx(n.id(), req); // Add new future. add(fut); } else // Add done future for testing. add(new GridFinishedFuture<GridCacheTx>(ctx)); } else { MiniFuture fut = new MiniFuture(m); req.miniId(fut.futureId()); add(fut); // Append new future. try { cctx.io().send(n, req); // If we don't wait for result, then mark future as done. if (!isSync() && !m.explicitLock()) fut.onDone(); } catch (GridTopologyException e) { // Remove previous mapping. mappings.remove(m.node().id()); fut.onResult(e); } catch (GridException e) { // Fail the whole thing. fut.onResult(e); } } }
/** * @param cctx Context. * @param tx Transaction. * @param commit Commit flag. */ public GridNearTxFinishFuture( GridCacheContext<K, V> cctx, GridNearTxLocal<K, V> tx, boolean commit) { super(cctx.kernalContext(), F.<GridCacheTx>identityReducer(tx)); assert cctx != null; this.cctx = cctx; this.tx = tx; this.commit = commit; mappings = tx.mappings(); futId = GridUuid.randomUuid(); log = U.logger(ctx, logRef, GridNearTxFinishFuture.class); }
/** * Mini-future for get operations. Mini-futures are only waiting on a single node as opposed to * multiple nodes. */ private class MiniFuture extends GridFutureAdapter<GridCacheTx> { /** */ private final GridUuid futId = GridUuid.randomUuid(); /** Keys. */ @GridToStringInclude private GridDistributedTxMapping<K, V> m; /** Empty constructor required for {@link Externalizable}. */ public MiniFuture() { // No-op. } /** @param m Mapping. */ MiniFuture(GridDistributedTxMapping<K, V> m) { super(cctx.kernalContext()); this.m = m; } /** @return Future ID. */ GridUuid futureId() { return futId; } /** @return Node ID. */ public GridRichNode node() { return m.node(); } /** @return Keys. */ public GridDistributedTxMapping<K, V> mapping() { return m; } /** @param e Error. */ void onResult(Throwable e) { if (log.isDebugEnabled()) log.debug("Failed to get future result [fut=" + this + ", err=" + e + ']'); // Fail. onDone(e); } /** @param e Node failure. */ void onResult(GridTopologyException e) { if (log.isDebugEnabled()) log.debug( "Remote node left grid while sending or waiting for reply (will ignore): " + this); onDone(tx); } /** @param res Result callback. */ void onResult(GridNearTxFinishResponse<K, V> res) { onDone(tx); } /** {@inheritDoc} */ @Override public String toString() { return S.toString( MiniFuture.class, this, "done", isDone(), "cancelled", isCancelled(), "err", error()); } }