use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class GridNearOptimisticTxPrepareFuture method map.
/**
* @param entry Transaction entry.
* @param topVer Topology version.
* @param cur Current mapping.
* @param topLocked {@code True} if thread already acquired lock preventing topology change.
* @param remap Remap flag.
* @return Mapping.
*/
private GridDistributedTxMapping map(IgniteTxEntry entry, AffinityTopologyVersion topVer, @Nullable GridDistributedTxMapping cur, boolean topLocked, boolean remap) {
GridCacheContext cacheCtx = entry.context();
List<ClusterNode> nodes;
GridCacheEntryEx cached0 = entry.cached();
if (cached0.isDht())
nodes = cacheCtx.topology().nodes(cached0.partition(), topVer);
else
nodes = cacheCtx.isLocal() ? cacheCtx.affinity().nodesByKey(entry.key(), topVer) : cacheCtx.topology().nodes(cacheCtx.affinity().partition(entry.key()), topVer);
if (F.isEmpty(nodes)) {
ClusterTopologyServerNotFoundException e = new ClusterTopologyServerNotFoundException("Failed to map " + "keys to nodes (partition is not mapped to any node) [key=" + entry.key() + ", partition=" + cacheCtx.affinity().partition(entry.key()) + ", topVer=" + topVer + ']');
onDone(e);
return null;
}
txMapping.addMapping(nodes);
ClusterNode primary = F.first(nodes);
assert primary != null;
if (log.isDebugEnabled()) {
log.debug("Mapped key to primary node [key=" + entry.key() + ", part=" + cacheCtx.affinity().partition(entry.key()) + ", primary=" + U.toShortString(primary) + ", topVer=" + topVer + ']');
}
// Must re-initialize cached entry while holding topology lock.
if (cacheCtx.isNear())
entry.cached(cacheCtx.nearTx().entryExx(entry.key(), topVer));
else if (!cacheCtx.isLocal())
entry.cached(cacheCtx.colocated().entryExx(entry.key(), topVer, true));
else
entry.cached(cacheCtx.local().entryEx(entry.key(), topVer));
if (cacheCtx.isNear() || cacheCtx.isLocal()) {
if (entry.explicitVersion() == null && !remap) {
if (keyLockFut == null) {
keyLockFut = new KeyLockFuture();
add(keyLockFut);
}
keyLockFut.addLockKey(entry.txKey());
}
}
if (cur == null || !cur.primary().id().equals(primary.id()) || (primary.isLocal() && cur.hasNearCacheEntries() != cacheCtx.isNear())) {
boolean clientFirst = cur == null && !topLocked && cctx.kernalContext().clientNode();
cur = new GridDistributedTxMapping(primary);
cur.clientFirst(clientFirst);
}
cur.add(entry);
if (entry.explicitVersion() != null) {
tx.markExplicit(primary.id());
cur.markExplicitLock();
}
entry.nodeId(primary.id());
if (cacheCtx.isNear()) {
while (true) {
try {
GridNearCacheEntry cached = (GridNearCacheEntry) entry.cached();
cached.dhtNodeId(tx.xidVersion(), primary.id());
break;
} catch (GridCacheEntryRemovedException ignore) {
entry.cached(cacheCtx.near().entryEx(entry.key(), topVer));
}
}
}
return cur;
}
use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class GridNearPessimisticTxPrepareFuture method preparePessimistic.
/**
*/
private void preparePessimistic() {
Map<UUID, GridDistributedTxMapping> mappings = new HashMap<>();
AffinityTopologyVersion topVer = tx.topologyVersion();
GridDhtTxMapping txMapping = new GridDhtTxMapping();
boolean hasNearCache = false;
for (IgniteTxEntry txEntry : tx.allEntries()) {
txEntry.clearEntryReadVersion();
GridCacheContext cacheCtx = txEntry.context();
if (cacheCtx.isNear())
hasNearCache = true;
List<ClusterNode> nodes;
if (!cacheCtx.isLocal()) {
GridDhtPartitionTopology top = cacheCtx.topology();
nodes = top.nodes(cacheCtx.affinity().partition(txEntry.key()), topVer);
} else
nodes = cacheCtx.affinity().nodesByKey(txEntry.key(), topVer);
if (F.isEmpty(nodes)) {
onDone(new ClusterTopologyServerNotFoundException("Failed to map keys to nodes (partition " + "is not mapped to any node) [key=" + txEntry.key() + ", partition=" + cacheCtx.affinity().partition(txEntry.key()) + ", topVer=" + topVer + ']'));
return;
}
ClusterNode primary = nodes.get(0);
GridDistributedTxMapping nodeMapping = mappings.get(primary.id());
if (nodeMapping == null)
mappings.put(primary.id(), nodeMapping = new GridDistributedTxMapping(primary));
txEntry.nodeId(primary.id());
nodeMapping.add(txEntry);
txMapping.addMapping(nodes);
}
tx.transactionNodes(txMapping.transactionNodes());
if (!hasNearCache)
checkOnePhase(txMapping);
long timeout = tx.remainingTime();
if (timeout == -1) {
onDone(new IgniteTxTimeoutCheckedException("Transaction timed out and was rolled back: " + tx));
return;
}
int miniId = 0;
Map<UUID, Collection<UUID>> txNodes = txMapping.transactionNodes();
for (final GridDistributedTxMapping m : mappings.values()) {
final ClusterNode primary = m.primary();
if (primary.isLocal()) {
if (m.hasNearCacheEntries() && m.hasColocatedCacheEntries()) {
GridNearTxPrepareRequest nearReq = createRequest(txMapping.transactionNodes(), m, timeout, m.nearEntriesReads(), m.nearEntriesWrites());
prepareLocal(nearReq, m, ++miniId, true);
GridNearTxPrepareRequest colocatedReq = createRequest(txNodes, m, timeout, m.colocatedEntriesReads(), m.colocatedEntriesWrites());
prepareLocal(colocatedReq, m, ++miniId, false);
} else {
GridNearTxPrepareRequest req = createRequest(txNodes, m, timeout, m.reads(), m.writes());
prepareLocal(req, m, ++miniId, m.hasNearCacheEntries());
}
} else {
GridNearTxPrepareRequest req = createRequest(txNodes, m, timeout, m.reads(), m.writes());
final MiniFuture fut = new MiniFuture(m, ++miniId);
req.miniId(fut.futureId());
add(fut);
try {
cctx.io().send(primary, req, tx.ioPolicy());
if (msgLog.isDebugEnabled()) {
msgLog.debug("Near pessimistic prepare, sent request [txId=" + tx.nearXidVersion() + ", node=" + primary.id() + ']');
}
} catch (ClusterTopologyCheckedException e) {
e.retryReadyFuture(cctx.nextAffinityReadyFuture(topVer));
fut.onNodeLeft(e);
} catch (IgniteCheckedException e) {
if (msgLog.isDebugEnabled()) {
msgLog.debug("Near pessimistic prepare, failed send request [txId=" + tx.nearXidVersion() + ", node=" + primary.id() + ", err=" + e + ']');
}
fut.onError(e);
break;
}
}
}
markInitialized();
}
use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class IgniteKernal method onDisconnected.
/**
*/
public void onDisconnected() {
Throwable err = null;
reconnectState.waitPreviousReconnect();
GridFutureAdapter<?> reconnectFut = ctx.gateway().onDisconnected();
if (reconnectFut == null) {
assert ctx.gateway().getState() != STARTED : ctx.gateway().getState();
return;
}
IgniteFutureImpl<?> curFut = (IgniteFutureImpl<?>) ctx.cluster().get().clientReconnectFuture();
IgniteFuture<?> userFut;
// In case of previous reconnect did not finish keep reconnect future.
if (curFut != null && curFut.internalFuture() == reconnectFut)
userFut = curFut;
else {
userFut = new IgniteFutureImpl<>(reconnectFut);
ctx.cluster().get().clientReconnectFuture(userFut);
}
ctx.disconnected(true);
List<GridComponent> comps = ctx.components();
for (ListIterator<GridComponent> it = comps.listIterator(comps.size()); it.hasPrevious(); ) {
GridComponent comp = it.previous();
try {
if (!skipDaemon(comp))
comp.onDisconnected(userFut);
} catch (IgniteCheckedException e) {
err = e;
} catch (Throwable e) {
err = e;
if (e instanceof Error)
throw e;
}
}
for (GridCacheContext cctx : ctx.cache().context().cacheContexts()) {
cctx.gate().writeLock();
cctx.gate().writeUnlock();
}
ctx.gateway().writeLock();
ctx.gateway().writeUnlock();
if (err != null) {
reconnectFut.onDone(err);
U.error(log, "Failed to reconnect, will stop node", err);
close();
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class CacheContinuousQueryHandler method register.
/**
* {@inheritDoc}
*/
@Override
public RegisterStatus register(final UUID nodeId, final UUID routineId, final GridKernalContext ctx) throws IgniteCheckedException {
assert nodeId != null;
assert routineId != null;
assert ctx != null;
if (locLsnr != null) {
if (locLsnr instanceof JCacheQueryLocalListener) {
ctx.resource().injectGeneric(((JCacheQueryLocalListener) locLsnr).impl);
asyncCb = ((JCacheQueryLocalListener) locLsnr).async();
} else {
ctx.resource().injectGeneric(locLsnr);
asyncCb = U.hasAnnotation(locLsnr, IgniteAsyncCallback.class);
}
}
final CacheEntryEventFilter filter = getEventFilter();
if (filter != null) {
if (filter instanceof JCacheQueryRemoteFilter) {
if (((JCacheQueryRemoteFilter) filter).impl != null)
ctx.resource().injectGeneric(((JCacheQueryRemoteFilter) filter).impl);
if (!asyncCb)
asyncCb = ((JCacheQueryRemoteFilter) filter).async();
} else {
ctx.resource().injectGeneric(filter);
if (!asyncCb)
asyncCb = U.hasAnnotation(filter, IgniteAsyncCallback.class);
}
}
entryBufs = new ConcurrentHashMap<>();
ackBuf = new CacheContinuousQueryAcknowledgeBuffer();
rcvs = new ConcurrentHashMap<>();
this.nodeId = nodeId;
this.routineId = routineId;
this.ctx = ctx;
final boolean loc = nodeId.equals(ctx.localNodeId());
assert !skipPrimaryCheck || loc;
log = ctx.log(CU.CONTINUOUS_QRY_LOG_CATEGORY);
CacheContinuousQueryListener<K, V> lsnr = new CacheContinuousQueryListener<K, V>() {
@Override
public void onExecution() {
GridCacheContext<K, V> cctx = cacheContext(ctx);
if (cctx != null && cctx.events().isRecordable(EVT_CACHE_QUERY_EXECUTED)) {
ctx.event().record(new CacheQueryExecutedEvent<>(ctx.discovery().localNode(), "Continuous query executed.", EVT_CACHE_QUERY_EXECUTED, CacheQueryType.CONTINUOUS.name(), cacheName, null, null, null, filter instanceof CacheEntryEventSerializableFilter ? (CacheEntryEventSerializableFilter) filter : null, null, nodeId, taskName()));
}
}
@Override
public boolean keepBinary() {
return keepBinary;
}
@Override
public void onEntryUpdated(final CacheContinuousQueryEvent<K, V> evt, boolean primary, final boolean recordIgniteEvt, GridDhtAtomicAbstractUpdateFuture fut) {
if (ignoreExpired && evt.getEventType() == EventType.EXPIRED)
return;
if (log.isDebugEnabled())
log.debug("Entry updated on affinity node [evt=" + evt + ", primary=" + primary + ']');
final GridCacheContext<K, V> cctx = cacheContext(ctx);
// Check that cache stopped.
if (cctx == null)
return;
// skipPrimaryCheck is set only when listen locally for replicated cache events.
assert !skipPrimaryCheck || (cctx.isReplicated() && ctx.localNodeId().equals(nodeId));
if (asyncCb) {
ContinuousQueryAsyncClosure clsr = new ContinuousQueryAsyncClosure(primary, evt, recordIgniteEvt, fut);
ctx.asyncCallbackPool().execute(clsr, evt.partitionId());
} else {
final boolean notify = filter(evt);
if (log.isDebugEnabled())
log.debug("Filter invoked for event [evt=" + evt + ", primary=" + primary + ", notify=" + notify + ']');
if (primary || skipPrimaryCheck) {
if (fut == null)
onEntryUpdate(evt, notify, loc, recordIgniteEvt);
else {
fut.addContinuousQueryClosure(new CI1<Boolean>() {
@Override
public void apply(Boolean suc) {
if (!suc)
evt.entry().markFiltered();
onEntryUpdate(evt, notify, loc, recordIgniteEvt);
}
}, sync);
}
} else
handleBackupEntry(cctx, evt.entry());
}
}
@Override
public void onUnregister() {
if (filter instanceof PlatformContinuousQueryFilter)
((PlatformContinuousQueryFilter) filter).onQueryUnregister();
}
@Override
public void cleanupBackupQueue(Map<Integer, Long> updateCntrs) {
for (Map.Entry<Integer, Long> e : updateCntrs.entrySet()) {
CacheContinuousQueryEventBuffer buf = entryBufs.get(e.getKey());
if (buf != null)
buf.cleanupBackupQueue(e.getValue());
}
}
@Override
public void flushBackupQueue(GridKernalContext ctx, AffinityTopologyVersion topVer) {
assert topVer != null;
try {
GridCacheContext<K, V> cctx = cacheContext(ctx);
ClusterNode node = ctx.discovery().node(nodeId);
for (Map.Entry<Integer, CacheContinuousQueryEventBuffer> bufE : entryBufs.entrySet()) {
CacheContinuousQueryEventBuffer buf = bufE.getValue();
Collection<CacheContinuousQueryEntry> backupQueue = buf.flushOnExchange();
if (backupQueue != null && node != null) {
for (CacheContinuousQueryEntry e : backupQueue) {
e.markBackup();
if (!e.isFiltered())
prepareEntry(cctx, nodeId, e);
}
ctx.continuous().addBackupNotification(nodeId, routineId, backupQueue, topic);
}
}
} catch (IgniteCheckedException e) {
U.error(ctx.log(CU.CONTINUOUS_QRY_LOG_CATEGORY), "Failed to send backup event notification to node: " + nodeId, e);
}
}
@Override
public void acknowledgeBackupOnTimeout(GridKernalContext ctx) {
sendBackupAcknowledge(ackBuf.acknowledgeOnTimeout(), routineId, ctx);
}
@Override
public void skipUpdateEvent(CacheContinuousQueryEvent<K, V> evt, AffinityTopologyVersion topVer, boolean primary) {
assert evt != null;
CacheContinuousQueryEntry e = evt.entry();
e.markFiltered();
onEntryUpdated(evt, primary, false, null);
}
@Override
public CounterSkipContext skipUpdateCounter(final GridCacheContext cctx, @Nullable CounterSkipContext skipCtx, int part, long cntr, AffinityTopologyVersion topVer, boolean primary) {
if (skipCtx == null)
skipCtx = new CounterSkipContext(part, cntr, topVer);
if (loc) {
assert !locCache;
final Collection<CacheEntryEvent<? extends K, ? extends V>> evts = handleEvent(ctx, skipCtx.entry());
if (!evts.isEmpty()) {
if (asyncCb) {
ctx.asyncCallbackPool().execute(new Runnable() {
@Override
public void run() {
notifyLocalListener(evts, getTransformer());
}
}, part);
} else
skipCtx.addProcessClosure(new Runnable() {
@Override
public void run() {
notifyLocalListener(evts, getTransformer());
}
});
}
return skipCtx;
}
CacheContinuousQueryEventBuffer buf = partitionBuffer(cctx, part);
final Object entryOrList = buf.processEntry(skipCtx.entry(), !primary);
if (entryOrList != null) {
skipCtx.addProcessClosure(new Runnable() {
@Override
public void run() {
try {
ctx.continuous().addNotification(nodeId, routineId, entryOrList, topic, false, true);
} catch (ClusterTopologyCheckedException ex) {
if (log.isDebugEnabled())
log.debug("Failed to send event notification to node, node left cluster " + "[node=" + nodeId + ", err=" + ex + ']');
} catch (IgniteCheckedException ex) {
U.error(ctx.log(CU.CONTINUOUS_QRY_LOG_CATEGORY), "Failed to send event notification to node: " + nodeId, ex);
}
}
});
}
return skipCtx;
}
@Override
public void onPartitionEvicted(int part) {
entryBufs.remove(part);
}
@Override
public boolean oldValueRequired() {
return oldValRequired;
}
@Override
public boolean notifyExisting() {
return notifyExisting;
}
private String taskName() {
return ctx.security().enabled() ? ctx.task().resolveTaskName(taskHash) : null;
}
};
CacheContinuousQueryManager mgr = manager(ctx);
if (mgr == null)
return RegisterStatus.DELAYED;
return mgr.registerListener(routineId, lsnr, internal);
}
use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class CacheContinuousQueryHandler method notifyCallback0.
/**
* @param nodeId Node id.
* @param ctx Kernal context.
* @param entries Entries.
*/
private void notifyCallback0(UUID nodeId, final GridKernalContext ctx, Collection<CacheContinuousQueryEntry> entries) {
final GridCacheContext cctx = cacheContext(ctx);
if (cctx == null) {
IgniteLogger log = ctx.log(CU.CONTINUOUS_QRY_LOG_CATEGORY);
if (log.isDebugEnabled())
log.debug("Failed to notify callback, cache is not found: " + cacheId);
return;
}
final Collection<CacheEntryEvent<? extends K, ? extends V>> entries0 = new ArrayList<>(entries.size());
for (CacheContinuousQueryEntry e : entries) {
GridCacheDeploymentManager depMgr = cctx.deploy();
ClassLoader ldr = depMgr.globalLoader();
if (ctx.config().isPeerClassLoadingEnabled()) {
GridDeploymentInfo depInfo = e.deployInfo();
if (depInfo != null) {
depMgr.p2pContext(nodeId, depInfo.classLoaderId(), depInfo.userVersion(), depInfo.deployMode(), depInfo.participants());
}
}
try {
e.unmarshal(cctx, ldr);
Collection<CacheEntryEvent<? extends K, ? extends V>> evts = handleEvent(ctx, e);
if (evts != null && !evts.isEmpty())
entries0.addAll(evts);
} catch (IgniteCheckedException ex) {
if (ignoreClsNotFound)
assert internal;
else
U.error(ctx.log(CU.CONTINUOUS_QRY_LOG_CATEGORY), "Failed to unmarshal entry.", ex);
}
}
notifyLocalListener(entries0, returnValTrans);
}
Aggregations