use of org.apache.ignite.internal.util.typedef.C2 in project ignite by apache.
the class GridDhtColocatedLockFuture method lockLocally.
/**
* Locks given keys directly through dht cache.
* @param keys Collection of keys.
* @param topVer Topology version to lock on.
*/
private void lockLocally(final Collection<KeyCacheObject> keys, AffinityTopologyVersion topVer) {
if (log.isDebugEnabled())
log.debug("Before locally locking keys : " + keys);
IgniteInternalFuture<Exception> fut = cctx.colocated().lockAllAsync(cctx, tx, threadId, lockVer, topVer, keys, read, retval, timeout, createTtl, accessTtl, filter, skipStore, keepBinary);
// Add new future.
add(new GridEmbeddedFuture<>(new C2<Exception, Exception, Boolean>() {
@Override
public Boolean apply(Exception resEx, Exception e) {
if (CU.isLockTimeoutOrCancelled(e) || (resEx != null && CU.isLockTimeoutOrCancelled(resEx)))
return false;
if (e != null) {
onError(e);
return false;
}
if (resEx != null) {
onError(resEx);
return false;
}
if (log.isDebugEnabled())
log.debug("Acquired lock for local DHT mapping [locId=" + cctx.nodeId() + ", mappedKeys=" + keys + ", fut=" + GridDhtColocatedLockFuture.this + ']');
if (inTx()) {
for (KeyCacheObject key : keys) tx.entry(cctx.txKey(key)).markLocked();
} else {
for (KeyCacheObject key : keys) cctx.mvcc().markExplicitOwner(cctx.txKey(key), threadId);
}
try {
// Proceed and add new future (if any) before completing embedded future.
if (mappings != null)
proceedMapping();
} catch (IgniteCheckedException ex) {
onError(ex);
return false;
}
return true;
}
}, fut));
}
use of org.apache.ignite.internal.util.typedef.C2 in project ignite by apache.
the class GridNearLockFuture method proceedMapping0.
/**
* Gets next near lock mapping and either acquires dht locks locally or sends near lock request to
* remote primary node.
*
* @throws IgniteCheckedException If mapping can not be completed.
*/
@SuppressWarnings("unchecked")
private void proceedMapping0() throws IgniteCheckedException {
GridNearLockMapping map;
synchronized (this) {
map = mappings.poll();
}
// If there are no more mappings to process, complete the future.
if (map == null)
return;
final GridNearLockRequest req = map.request();
final Collection<KeyCacheObject> mappedKeys = map.distributedKeys();
final ClusterNode node = map.node();
if (filter != null && filter.length != 0)
req.filter(filter, cctx);
if (node.isLocal()) {
req.miniId(-1);
if (log.isDebugEnabled())
log.debug("Before locally locking near request: " + req);
IgniteInternalFuture<GridNearLockResponse> fut = dht().lockAllAsync(cctx, cctx.localNode(), req, filter);
// Add new future.
add(new GridEmbeddedFuture<>(new C2<GridNearLockResponse, Exception, Boolean>() {
@Override
public Boolean apply(GridNearLockResponse res, Exception e) {
if (CU.isLockTimeoutOrCancelled(e) || (res != null && CU.isLockTimeoutOrCancelled(res.error())))
return false;
if (e != null) {
onError(e);
return false;
}
if (res == null) {
onError(new IgniteCheckedException("Lock response is null for future: " + this));
return false;
}
if (res.error() != null) {
onError(res.error());
return false;
}
if (log.isDebugEnabled())
log.debug("Acquired lock for local DHT mapping [locId=" + cctx.nodeId() + ", mappedKeys=" + mappedKeys + ", fut=" + GridNearLockFuture.this + ']');
try {
int i = 0;
for (KeyCacheObject k : mappedKeys) {
while (true) {
GridNearCacheEntry entry = cctx.near().entryExx(k, req.topologyVersion());
try {
IgniteBiTuple<GridCacheVersion, CacheObject> oldValTup = valMap.get(entry.key());
boolean hasBytes = entry.hasValue();
CacheObject oldVal = entry.rawGet();
CacheObject newVal = res.value(i);
GridCacheVersion dhtVer = res.dhtVersion(i);
GridCacheVersion mappedVer = res.mappedVersion(i);
// On local node don't record twice if DHT cache already recorded.
boolean record = retval && oldValTup != null && oldValTup.get1().equals(dhtVer);
if (newVal == null) {
if (oldValTup != null) {
if (oldValTup.get1().equals(dhtVer))
newVal = oldValTup.get2();
oldVal = oldValTup.get2();
}
}
// Lock is held at this point, so we can set the
// returned value if any.
entry.resetFromPrimary(newVal, lockVer, dhtVer, node.id(), topVer);
entry.readyNearLock(lockVer, mappedVer, res.committedVersions(), res.rolledbackVersions(), res.pending());
if (inTx() && implicitTx() && tx.onePhaseCommit()) {
boolean pass = res.filterResult(i);
tx.entry(cctx.txKey(k)).filters(pass ? CU.empty0() : CU.alwaysFalse0Arr());
}
if (record) {
if (cctx.events().isRecordable(EVT_CACHE_OBJECT_READ))
cctx.events().addEvent(entry.partition(), entry.key(), tx, null, EVT_CACHE_OBJECT_READ, newVal, newVal != null, oldVal, hasBytes, CU.subjectId(tx, cctx.shared()), null, inTx() ? tx.resolveTaskName() : null, keepBinary);
if (cctx.cache().configuration().isStatisticsEnabled())
cctx.cache().metrics0().onRead(oldVal != null);
}
if (log.isDebugEnabled())
log.debug("Processed response for entry [res=" + res + ", entry=" + entry + ']');
// Inner while loop.
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Failed to add candidates because entry was " + "removed (will renew).");
synchronized (GridNearLockFuture.this) {
// Replace old entry with new one.
entries.set(i, (GridDistributedCacheEntry) cctx.cache().entryEx(entry.key()));
}
}
}
// Increment outside of while loop.
i++;
}
// Proceed and add new future (if any) before completing embedded future.
proceedMapping();
} catch (IgniteCheckedException ex) {
onError(ex);
return false;
}
return true;
}
}, fut));
} else {
final MiniFuture fut = new MiniFuture(node, mappedKeys, ++miniId);
req.miniId(fut.futureId());
// Append new future.
add(fut);
IgniteInternalFuture<?> txSync = null;
if (inTx())
txSync = cctx.tm().awaitFinishAckAsync(node.id(), tx.threadId());
if (txSync == null || txSync.isDone()) {
try {
if (log.isDebugEnabled())
log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']');
cctx.io().send(node, req, cctx.ioPolicy());
} catch (ClusterTopologyCheckedException ex) {
fut.onResult(ex);
}
} else {
txSync.listen(new CI1<IgniteInternalFuture<?>>() {
@Override
public void apply(IgniteInternalFuture<?> t) {
try {
if (log.isDebugEnabled())
log.debug("Sending near lock request [node=" + node.id() + ", req=" + req + ']');
cctx.io().send(node, req, cctx.ioPolicy());
} catch (ClusterTopologyCheckedException ex) {
fut.onResult(ex);
} catch (IgniteCheckedException e) {
onError(e);
}
}
});
}
}
}
use of org.apache.ignite.internal.util.typedef.C2 in project ignite by apache.
the class GridDhtGetFuture method getAsync.
/**
* @param keys Keys to get.
* @return Future for local get.
*/
@SuppressWarnings({ "unchecked", "IfMayBeConditional" })
private IgniteInternalFuture<Collection<GridCacheEntryInfo>> getAsync(final Map<KeyCacheObject, Boolean> keys) {
if (F.isEmpty(keys))
return new GridFinishedFuture<Collection<GridCacheEntryInfo>>(Collections.<GridCacheEntryInfo>emptyList());
String taskName0 = cctx.kernalContext().job().currentTaskName();
if (taskName0 == null)
taskName0 = cctx.kernalContext().task().resolveTaskName(taskNameHash);
final String taskName = taskName0;
GridCompoundFuture<Boolean, Boolean> txFut = null;
ClusterNode readerNode = cctx.discovery().node(reader);
ReaderArguments readerArgs = null;
if (readerNode != null && !readerNode.isLocal() && cctx.discovery().cacheNearNode(readerNode, cctx.name())) {
for (Map.Entry<KeyCacheObject, Boolean> k : keys.entrySet()) {
while (true) {
GridDhtCacheEntry e = cache().entryExx(k.getKey(), topVer);
try {
if (e.obsolete())
continue;
boolean addReader = (!e.deleted() && k.getValue() && !skipVals);
if (addReader) {
e.unswap(false);
// we have to add reader again later.
if (readerArgs == null)
readerArgs = new ReaderArguments(reader, msgId, topVer);
}
// Register reader. If there are active transactions for this entry,
// then will wait for their completion before proceeding.
// TODO: IGNITE-3498:
// TODO: What if any transaction we wait for actually removes this entry?
// TODO: In this case seems like we will be stuck with untracked near entry.
// TODO: To fix, check that reader is contained in the list of readers once
// TODO: again after the returned future completes - if not, try again.
IgniteInternalFuture<Boolean> f = addReader ? e.addReader(reader, msgId, topVer) : null;
if (f != null) {
if (txFut == null)
txFut = new GridCompoundFuture<>(CU.boolReducer());
txFut.add(f);
}
break;
} catch (IgniteCheckedException err) {
return new GridFinishedFuture<>(err);
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed entry when getting a DHT value: " + e);
} finally {
cctx.evicts().touch(e, topVer);
}
}
}
if (txFut != null)
txFut.markInitialized();
}
IgniteInternalFuture<Map<KeyCacheObject, EntryGetResult>> fut;
if (txFut == null || txFut.isDone()) {
fut = cache().getDhtAllAsync(keys.keySet(), readerArgs, readThrough, subjId, taskName, expiryPlc, skipVals, /*can remap*/
true, recovery);
} else {
final ReaderArguments args = readerArgs;
// If we are here, then there were active transactions for some entries
// when we were adding the reader. In that case we must wait for those
// transactions to complete.
fut = new GridEmbeddedFuture<>(txFut, new C2<Boolean, Exception, IgniteInternalFuture<Map<KeyCacheObject, EntryGetResult>>>() {
@Override
public IgniteInternalFuture<Map<KeyCacheObject, EntryGetResult>> apply(Boolean b, Exception e) {
if (e != null)
throw new GridClosureException(e);
return cache().getDhtAllAsync(keys.keySet(), args, readThrough, subjId, taskName, expiryPlc, skipVals, /*can remap*/
true, recovery);
}
});
}
if (fut.isDone()) {
if (fut.error() != null)
onDone(fut.error());
else
return new GridFinishedFuture<>(toEntryInfos(fut.result()));
}
return new GridEmbeddedFuture<>(new C2<Map<KeyCacheObject, EntryGetResult>, Exception, Collection<GridCacheEntryInfo>>() {
@Override
public Collection<GridCacheEntryInfo> apply(Map<KeyCacheObject, EntryGetResult> map, Exception e) {
if (e != null) {
onDone(e);
return Collections.emptyList();
} else
return toEntryInfos(map);
}
}, fut);
}
Aggregations