use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GridPartitionedGetFuture method map.
/**
* @param keys Keys.
* @param mapped Mappings to check for duplicates.
* @param topVer Topology version on which keys should be mapped.
*/
private void map(Collection<KeyCacheObject> keys, Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mapped, AffinityTopologyVersion topVer) {
Collection<ClusterNode> cacheNodes = CU.affinityNodes(cctx, topVer);
if (cacheNodes.isEmpty()) {
onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache " + "(all partition nodes left the grid) [topVer=" + topVer + ", cache=" + cctx.name() + ']'));
return;
}
GridDhtTopologyFuture topFut = cctx.shared().exchange().lastFinishedFuture();
Throwable err = topFut != null ? topFut.validateCache(cctx, recovery, true, null, keys) : null;
if (err != null) {
onDone(err);
return;
}
Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings = U.newHashMap(cacheNodes.size());
final int keysSize = keys.size();
Map<K, V> locVals = U.newHashMap(keysSize);
boolean hasRmtNodes = false;
// Assign keys to primary nodes.
for (KeyCacheObject key : keys) hasRmtNodes |= map(key, mappings, locVals, topVer, mapped);
if (isDone())
return;
if (!locVals.isEmpty())
add(new GridFinishedFuture<>(locVals));
if (hasRmtNodes) {
if (!trackable) {
trackable = true;
cctx.mvcc().addFuture(this, futId);
}
}
// Create mini futures.
for (Map.Entry<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> entry : mappings.entrySet()) {
final ClusterNode n = entry.getKey();
final LinkedHashMap<KeyCacheObject, Boolean> mappedKeys = entry.getValue();
assert !mappedKeys.isEmpty();
// If this is the primary or backup node for the keys.
if (n.isLocal()) {
final GridDhtFuture<Collection<GridCacheEntryInfo>> fut = cache().getDhtAsync(n.id(), -1, mappedKeys, readThrough, topVer, subjId, taskName == null ? 0 : taskName.hashCode(), expiryPlc, skipVals, recovery);
final Collection<Integer> invalidParts = fut.invalidPartitions();
if (!F.isEmpty(invalidParts)) {
Collection<KeyCacheObject> remapKeys = new ArrayList<>(keysSize);
for (KeyCacheObject key : keys) {
if (key != null && invalidParts.contains(cctx.affinity().partition(key)))
remapKeys.add(key);
}
AffinityTopologyVersion updTopVer = cctx.discovery().topologyVersionEx();
assert updTopVer.compareTo(topVer) > 0 : "Got invalid partitions for local node but topology version did " + "not change [topVer=" + topVer + ", updTopVer=" + updTopVer + ", invalidParts=" + invalidParts + ']';
// Remap recursively.
map(remapKeys, mappings, updTopVer);
}
// Add new future.
add(fut.chain(new C1<IgniteInternalFuture<Collection<GridCacheEntryInfo>>, Map<K, V>>() {
@Override
public Map<K, V> apply(IgniteInternalFuture<Collection<GridCacheEntryInfo>> fut) {
try {
return createResultMap(fut.get());
} catch (Exception e) {
U.error(log, "Failed to get values from dht cache [fut=" + fut + "]", e);
onDone(e);
return Collections.emptyMap();
}
}
}));
} else {
MiniFuture fut = new MiniFuture(n, mappedKeys, topVer);
GridCacheMessage req = new GridNearGetRequest(cctx.cacheId(), futId, fut.futureId(), null, mappedKeys, readThrough, topVer, subjId, taskName == null ? 0 : taskName.hashCode(), expiryPlc != null ? expiryPlc.forCreate() : -1L, expiryPlc != null ? expiryPlc.forAccess() : -1L, skipVals, cctx.deploymentEnabled(), recovery);
// Append new future.
add(fut);
try {
cctx.io().send(n, req, cctx.ioPolicy());
} catch (IgniteCheckedException e) {
// Fail the whole thing.
if (e instanceof ClusterTopologyCheckedException)
fut.onNodeLeft((ClusterTopologyCheckedException) e);
else
fut.onResult(e);
}
}
}
}
use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GridCacheMvccManager method finishLocks.
/**
* @param filter Entry filter.
* @param topVer Topology version.
* @return Future that signals when all locks for given partitions will be released.
*/
private IgniteInternalFuture<?> finishLocks(@Nullable final IgnitePredicate<GridDistributedCacheEntry> filter, AffinityTopologyVersion topVer) {
assert topVer.topologyVersion() != 0;
if (topVer.equals(AffinityTopologyVersion.NONE))
return new GridFinishedFuture();
final FinishLockFuture finishFut = new FinishLockFuture(filter == null ? locked() : F.view(locked(), filter), topVer);
finishFuts.add(finishFut);
finishFut.listen(new CI1<IgniteInternalFuture<?>>() {
@Override
public void apply(IgniteInternalFuture<?> e) {
finishFuts.remove(finishFut);
}
});
finishFut.recheck();
return finishFut;
}
use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GridCacheAdapter method asyncOp.
/**
* @param tx Transaction.
* @param op Cache operation.
* @param opCtx Cache operation context.
* @param <T> Return type.
* @return Future.
*/
@SuppressWarnings("unchecked")
protected <T> IgniteInternalFuture<T> asyncOp(GridNearTxLocal tx, final AsyncOp<T> op, final CacheOperationContext opCtx, final boolean retry) {
IgniteInternalFuture<T> fail = asyncOpAcquire(retry);
if (fail != null)
return fail;
FutureHolder holder = lastFut.get();
holder.lock();
try {
IgniteInternalFuture fut = holder.future();
final GridNearTxLocal tx0 = tx;
if (fut != null && !fut.isDone()) {
IgniteInternalFuture<T> f = new GridEmbeddedFuture(fut, new IgniteOutClosure<IgniteInternalFuture>() {
@Override
public IgniteInternalFuture<T> apply() {
if (ctx.kernalContext().isStopping())
return new GridFinishedFuture<>(new IgniteCheckedException("Operation has been cancelled (node is stopping)."));
return op.op(tx0, opCtx).chain(new CX1<IgniteInternalFuture<T>, T>() {
@Override
public T applyx(IgniteInternalFuture<T> tFut) throws IgniteCheckedException {
try {
return tFut.get();
} catch (IgniteTxRollbackCheckedException e) {
throw e;
} catch (IgniteCheckedException e1) {
tx0.rollbackNearTxLocalAsync();
throw e1;
} finally {
ctx.shared().txContextReset();
}
}
});
}
});
saveFuture(holder, f, retry);
return f;
}
final IgniteInternalFuture<T> f = op.op(tx, opCtx).chain(new CX1<IgniteInternalFuture<T>, T>() {
@Override
public T applyx(IgniteInternalFuture<T> tFut) throws IgniteCheckedException {
try {
return tFut.get();
} catch (IgniteTxRollbackCheckedException e) {
throw e;
} catch (IgniteCheckedException e1) {
tx0.rollbackNearTxLocalAsync();
throw e1;
} finally {
ctx.shared().txContextReset();
}
}
});
saveFuture(holder, f, retry);
if (tx.implicit())
ctx.tm().resetContext();
return f;
} finally {
holder.unlock();
}
}
use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GridNearTxLocal method prepareAsyncLocal.
/**
* Prepares next batch of entries in dht transaction.
*
* @param reads Read entries.
* @param writes Write entries.
* @param txNodes Transaction nodes mapping.
* @param last {@code True} if this is last prepare request.
* @return Future that will be completed when locks are acquired.
*/
@SuppressWarnings("TypeMayBeWeakened")
public IgniteInternalFuture<GridNearTxPrepareResponse> prepareAsyncLocal(@Nullable Collection<IgniteTxEntry> reads, @Nullable Collection<IgniteTxEntry> writes, Map<UUID, Collection<UUID>> txNodes, boolean last) {
long timeout = remainingTime();
if (state() != PREPARING) {
if (timeout == -1)
return new GridFinishedFuture<>(new IgniteTxTimeoutCheckedException("Transaction timed out: " + this));
setRollbackOnly();
return new GridFinishedFuture<>(new IgniteCheckedException("Invalid transaction state for prepare [state=" + state() + ", tx=" + this + ']'));
}
if (timeout == -1)
return new GridFinishedFuture<>(timeoutException());
init();
GridDhtTxPrepareFuture fut = new GridDhtTxPrepareFuture(cctx, this, timeout, 0, Collections.<IgniteTxKey, GridCacheVersion>emptyMap(), last, needReturnValue() && implicit());
try {
userPrepare((serializable() && optimistic()) ? F.concat(false, writes, reads) : writes);
// Make sure to add future before calling prepare on it.
cctx.mvcc().addFuture(fut);
if (isSystemInvalidate())
fut.complete();
else
fut.prepare(reads, writes, txNodes);
} catch (IgniteTxTimeoutCheckedException | IgniteTxOptimisticCheckedException e) {
fut.onError(e);
} catch (IgniteCheckedException e) {
setRollbackOnly();
fut.onError(new IgniteTxRollbackCheckedException("Failed to prepare transaction: " + this, e));
try {
rollback();
} catch (IgniteTxOptimisticCheckedException e1) {
if (log.isDebugEnabled())
log.debug("Failed optimistically to prepare transaction [tx=" + this + ", e=" + e1 + ']');
fut.onError(e);
} catch (IgniteCheckedException e1) {
U.error(log, "Failed to rollback transaction: " + this, e1);
}
}
return chainOnePhasePrepare(fut);
}
use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GridNearTxLocal method enlistWrite.
/**
* @param cacheCtx Cache context.
* @param cacheKey Key to enlist.
* @param val Value.
* @param expiryPlc Explicitly specified expiry policy for entry.
* @param entryProcessor Entry processor (for invoke operation).
* @param invokeArgs Optional arguments for EntryProcessor.
* @param retval Flag indicating whether a value should be returned.
* @param lockOnly If {@code true}, then entry will be enlisted as noop.
* @param filter User filters.
* @param ret Return value.
* @param skipStore Skip store flag.
* @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
* @return Future for entry values loading.
*/
private <K, V> IgniteInternalFuture<Void> enlistWrite(final GridCacheContext cacheCtx, @Nullable AffinityTopologyVersion entryTopVer, KeyCacheObject cacheKey, Object val, @Nullable ExpiryPolicy expiryPlc, @Nullable EntryProcessor<K, V, Object> entryProcessor, @Nullable Object[] invokeArgs, final boolean retval, boolean lockOnly, final CacheEntryPredicate[] filter, final GridCacheReturn ret, boolean skipStore, final boolean singleRmv, boolean keepBinary, boolean recovery, Byte dataCenterId) {
try {
addActiveCache(cacheCtx, recovery);
final boolean hasFilters = !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter);
final boolean needVal = singleRmv || retval || hasFilters;
final boolean needReadVer = needVal && (serializable() && optimistic());
if (entryProcessor != null)
transform = true;
GridCacheVersion drVer = dataCenterId != null ? cctx.versions().next(dataCenterId) : null;
boolean loadMissed = enlistWriteEntry(cacheCtx, entryTopVer, cacheKey, val, entryProcessor, invokeArgs, expiryPlc, retval, lockOnly, filter, /*drVer*/
drVer, /*drTtl*/
-1L, /*drExpireTime*/
-1L, ret, /*enlisted*/
null, skipStore, singleRmv, hasFilters, needVal, needReadVer, keepBinary, recovery);
if (loadMissed) {
AffinityTopologyVersion topVer = topologyVersionSnapshot();
if (topVer == null)
topVer = entryTopVer;
return loadMissing(cacheCtx, topVer != null ? topVer : topologyVersion(), Collections.singleton(cacheKey), filter, ret, needReadVer, singleRmv, hasFilters, /*read through*/
(entryProcessor != null || cacheCtx.config().isLoadPreviousValue()) && !skipStore, retval, keepBinary, recovery, expiryPlc);
}
return new GridFinishedFuture<>();
} catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(e);
}
}
Aggregations