/** * @param mapping Mappings. * @param key Key to map. * @param topVer Topology version. * @return Near lock mapping. * @throws GridException If mapping for key failed. */ private GridNearLockMapping<K, V> map( K key, @Nullable GridNearLockMapping<K, V> mapping, long topVer) throws GridException { assert mapping == null || mapping.node() != null; GridNode primary = cctx.affinity().primary(key, topVer); if (cctx.discovery().node(primary.id()) == null) // If primary node left the grid before lock acquisition, fail the whole future. throw newTopologyException(null, primary.id()); if (inTx() && tx.groupLock() && !primary.isLocal()) throw new GridException( "Failed to start group lock transaction (local node is not primary for " + " key) [key=" + key + ", primaryNodeId=" + primary.id() + ']'); if (mapping == null || !primary.id().equals(mapping.node().id())) mapping = new GridNearLockMapping<>(primary, key); else mapping.addKey(key); return mapping; }
/** * Completeness callback. * * @param success {@code True} if lock was acquired. * @param distribute {@code True} if need to distribute lock removal in case of failure. * @return {@code True} if complete by this operation. */ private boolean onComplete(boolean success, boolean distribute) { if (log.isDebugEnabled()) log.debug( "Received onComplete(..) callback [success=" + success + ", distribute=" + distribute + ", fut=" + this + ']'); if (!success) undoLocks(distribute); if (tx != null) cctx.tm().txContext(tx); if (super.onDone(success, err.get())) { if (log.isDebugEnabled()) log.debug("Completing future: " + this); // Clean up. cctx.mvcc().removeFuture(this); if (timeoutObj != null) cctx.time().removeTimeoutObject(timeoutObj); return true; } return false; }
/** @return Nodes to execute on. */ private Collection<GridNode> nodes() { GridCacheMode cacheMode = cctx.config().getCacheMode(); switch (cacheMode) { case LOCAL: if (prj != null) U.warn( log, "Ignoring query projection because it's executed over LOCAL cache " + "(only local node will be queried): " + this); return Collections.singletonList(cctx.localNode()); case REPLICATED: if (prj != null) return nodes(cctx, prj); GridCacheDistributionMode mode = cctx.config().getDistributionMode(); return mode == PARTITIONED_ONLY || mode == NEAR_PARTITIONED ? Collections.singletonList(cctx.localNode()) : Collections.singletonList(F.rand(nodes(cctx, null))); case PARTITIONED: return nodes(cctx, prj); default: throw new IllegalStateException("Unknown cache distribution mode: " + cacheMode); } }
/** {@inheritDoc} */ @Override public boolean onDone(GridCacheTx tx, Throwable err) { if ((initialized() || err != null) && super.onDone(tx, err)) { if (error() instanceof GridCacheTxHeuristicException) { long topVer = this.tx.topologyVersion(); for (GridCacheTxEntry<K, V> e : this.tx.writeMap().values()) { try { if (e.op() != NOOP && !cctx.affinity().localNode(e.key(), topVer)) { GridCacheEntryEx<K, V> cacheEntry = cctx.cache().peekEx(e.key()); if (cacheEntry != null) cacheEntry.invalidate(null, this.tx.xidVersion()); } } catch (Throwable t) { U.error(log, "Failed to invalidate entry.", t); if (t instanceof Error) throw (Error) t; } } } // Don't forget to clean up. cctx.mvcc().removeFuture(this); return true; } return false; }
/** {@inheritDoc} */ @Override public void prepareMarshal(GridCacheContext<K, V> ctx) throws GridException { super.prepareMarshal(ctx); if (entries != null) { if (ctx.deploymentEnabled()) prepareObjects(entries, ctx); entriesBytes = ctx.marshaller().marshal(entries); } }
/** * Creates MBean; * * @param cctx Cache context. */ GridCacheMBeanAdapter(GridCacheContext<?, ?> cctx) { assert cctx != null; this.cctx = cctx; if (cctx.isNear()) dhtCtx = cctx.near().dht().context(); if (cctx.config().isWriteFromBehindEnabled()) store = (GridCacheWriteFromBehindStore) cctx.cacheStore(); }
/** * @param rmtReducer Optional reducer. * @param rmtTransform Optional transformer. * @param args Arguments. * @return Future. */ @SuppressWarnings("IfMayBeConditional") private <R> GridCacheQueryFuture<R> execute( @Nullable GridReducer<T, R> rmtReducer, @Nullable GridClosure<T, R> rmtTransform, @Nullable Object... args) { Collection<GridNode> nodes = nodes(); cctx.checkSecurity(GridSecurityPermission.CACHE_READ); if (F.isEmpty(nodes)) return new GridCacheQueryErrorFuture<>( cctx.kernalContext(), new GridEmptyProjectionException("There are no data nodes for cache: " + cctx.namexx())); if (log.isDebugEnabled()) log.debug("Executing query [query=" + this + ", nodes=" + nodes + ']'); if (cctx.deploymentEnabled()) { try { cctx.deploy().registerClasses(filter, rmtReducer, rmtTransform); cctx.deploy().registerClasses(args); } catch (GridException e) { return new GridCacheQueryErrorFuture<>(cctx.kernalContext(), e); } } if (subjId == null) subjId = cctx.localNodeId(); taskHash = cctx.kernalContext().job().currentTaskNameHash(); GridCacheQueryBean bean = new GridCacheQueryBean( this, (GridReducer<Object, Object>) rmtReducer, (GridClosure<Object, Object>) rmtTransform, args); GridCacheQueryManager qryMgr = cctx.queries(); boolean loc = nodes.size() == 1 && F.first(nodes).id().equals(cctx.localNodeId()); if (type == SQL_FIELDS) return (GridCacheQueryFuture<R>) (loc ? qryMgr.queryFieldsLocal(bean) : qryMgr.queryFieldsDistributed(bean, nodes)); else return (GridCacheQueryFuture<R>) (loc ? qryMgr.queryLocal(bean) : qryMgr.queryDistributed(bean, nodes)); }
/** * Constructor. * * @param name Latch name. * @param cnt Current count. * @param initCnt Initial count. * @param autoDel Auto delete flag. * @param key Latch key. * @param latchView Latch projection. * @param ctx Cache context. */ public GridCacheCountDownLatchImpl( String name, int cnt, int initCnt, boolean autoDel, GridCacheInternalKey key, GridCacheProjection<GridCacheInternalKey, GridCacheCountDownLatchValue> latchView, GridCacheContext ctx) { assert name != null; assert cnt >= 0; assert initCnt >= 0; assert key != null; assert latchView != null; assert ctx != null; this.name = name; this.cnt = cnt; this.initCnt = initCnt; this.autoDel = autoDel; this.key = key; this.latchView = latchView; this.ctx = ctx; log = ctx.gridConfig().getGridLogger().getLogger(getClass()); }
/** * @param cctx Context. * @param type Query type. * @param clsName Class name. * @param clause Clause. * @param filter Scan filter. * @param incMeta Include metadata flag. * @param keepPortable Keep portable flag. * @param prjPred Cache projection filter. */ public GridCacheQueryAdapter( GridCacheContext<?, ?> cctx, GridCacheQueryType type, @Nullable GridPredicate<GridCacheEntry<Object, Object>> prjPred, @Nullable String clsName, @Nullable String clause, @Nullable GridBiPredicate<Object, Object> filter, boolean incMeta, boolean keepPortable) { assert cctx != null; assert type != null; this.cctx = cctx; this.type = type; this.clsName = clsName; this.clause = clause; this.prjPred = prjPred; this.filter = filter; this.incMeta = incMeta; this.keepPortable = keepPortable; log = cctx.logger(getClass()); pageSize = DFLT_PAGE_SIZE; timeout = 0; keepAll = true; incBackups = false; dedup = false; prj = null; metrics = new GridCacheQueryMetricsAdapter(); }
/** * @param ctx Cache context. * @param key Cache key. * @param hash Key hash value. * @param val Entry value. * @param next Next entry in the linked list. * @param ttl Time to live. */ public GridDhtCacheEntry( GridCacheContext<K, V> ctx, K key, int hash, V val, GridCacheMapEntry<K, V> next, long ttl) { super(ctx, key, hash, val, next, ttl); // Record this entry with partition. locPart = ctx.dht().topology().onAdded(this); }
/** {@inheritDoc} */ @Override public GridCacheEntry<K, V> wrap(boolean prjAware) { GridCacheContext<K, V> nearCtx = cctx.dht().near().context(); GridCacheProjectionImpl<K, V> prjPerCall = nearCtx.projectionPerCall(); if (prjPerCall != null && prjAware) return new GridPartitionedCacheEntryImpl<K, V>(prjPerCall, nearCtx, key, this); GridCacheEntryImpl<K, V> wrapper = this.wrapper; if (wrapper == null) this.wrapper = wrapper = new GridPartitionedCacheEntryImpl<K, V>(null, nearCtx, key, this); return wrapper; }
/** * @param ctx Cache registry. * @param implicit Implicit flag. * @param implicitSingle Implicit with one key flag. * @param concurrency Concurrency. * @param isolation Isolation. * @param timeout Timeout. * @param invalidate Invalidation policy. * @param syncCommit Synchronous commit flag. * @param syncRollback Synchronous rollback flag. * @param swapEnabled Whether to use swap storage. * @param storeEnabled Whether to use read/write through. */ GridNearTxLocal( GridCacheContext<K, V> ctx, boolean implicit, boolean implicitSingle, GridCacheTxConcurrency concurrency, GridCacheTxIsolation isolation, long timeout, boolean invalidate, boolean syncCommit, boolean syncRollback, boolean swapEnabled, boolean storeEnabled) { super( ctx, ctx.versions().next(), implicit, implicitSingle, concurrency, isolation, timeout, invalidate, swapEnabled, storeEnabled); assert ctx != null; this.syncCommit = syncCommit; this.syncRollback = syncRollback; }
/** * Adds a Near key. * * @param key Key. * @param keyBytes Key bytes. * @param ctx Context. * @throws GridException If failed. */ public void addNearKey(K key, byte[] keyBytes, GridCacheContext<K, V> ctx) throws GridException { if (ctx.deploymentEnabled()) prepareObject(key, ctx); if (nearKeyBytes == null) nearKeyBytes = new ArrayList<>(); nearKeyBytes.add(keyBytes); }
/** {@inheritDoc} */ @SuppressWarnings("TypeMayBeWeakened") @Nullable private Collection<byte[]> marshalFieldsCollection( @Nullable Collection<Object> col, GridCacheContext<K, V> ctx) throws GridException { assert ctx != null; if (col == null) return null; Collection<List<Object>> col0 = new ArrayList<>(col.size()); for (Object o : col) { List<GridIndexingEntity<?>> list = (List<GridIndexingEntity<?>>) o; List<Object> list0 = new ArrayList<>(list.size()); for (GridIndexingEntity<?> ent : list) { if (ent.bytes() != null) list0.add(ent.bytes()); else { if (ctx.deploymentEnabled()) prepareObject(ent.value(), ctx); list0.add(CU.marshal(ctx, ent.value())); } } col0.add(list0); } return marshalCollection(col0, ctx); }
/** {@inheritDoc} */ @SuppressWarnings("TypeMayBeWeakened") @Nullable private Collection<Object> unmarshalFieldsCollection( @Nullable Collection<byte[]> byteCol, GridCacheContext<K, V> ctx, ClassLoader ldr) throws GridException { assert ctx != null; assert ldr != null; Collection<Object> col = unmarshalCollection(byteCol, ctx, ldr); Collection<Object> col0 = null; if (col != null) { col0 = new ArrayList<>(col.size()); for (Object o : col) { List<Object> list = (List<Object>) o; List<Object> list0 = new ArrayList<>(list.size()); for (Object obj : list) list0.add(obj != null ? ctx.marshaller().unmarshal((byte[]) obj, ldr) : null); col0.add(list0); } } return col0; }
/** {@inheritDoc} */ @Override public long getOverflowSize() { try { return cctx.cache().overflowSize(); } catch (GridException ignored) { return -1; } }
/** @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 entry Transaction entry. * @param nodes Nodes. */ private void map(GridCacheTxEntry<K, V> entry, Collection<GridRichNode> nodes) { GridRichNode primary = CU.primary0(cctx.affinity(entry.key(), nodes)); GridDistributedTxMapping<K, V> t = mappings.get(primary.id()); if (t == null) mappings.put(primary.id(), t = new GridDistributedTxMapping<K, V>(primary)); t.add(entry); }
/** {@inheritDoc} */ @Override public void prepareMarshal(GridCacheContext<K, V> ctx) throws GridException { super.prepareMarshal(ctx); if (err != null) errBytes = ctx.marshaller().marshal(err); metaDataBytes = marshalCollection(metadata, ctx); dataBytes = fields ? marshalFieldsCollection(data, ctx) : marshalCollection(data, ctx); if (ctx.deploymentEnabled() && !F.isEmpty(data)) { for (Object o : data) { if (o instanceof Map.Entry) { Map.Entry e = (Map.Entry) o; prepareObject(e.getKey(), ctx); prepareObject(e.getValue(), ctx); } } } }
/** {@inheritDoc} */ @Override public boolean onDone(GridCacheTx tx, Throwable err) { if (initialized() && super.onDone(tx, err)) { // Don't forget to clean up. cctx.mvcc().removeFuture(this); return true; } return false; }
/** * Undoes all locks. * * @param dist If {@code true}, then remove locks from remote nodes as well. */ private void undoLocks(boolean dist) { // Transactions will undo during rollback. if (dist && tx == null) cctx.nearTx().removeLocks(lockVer, keys); else { if (tx != null) { if (tx.setRollbackOnly()) { if (log.isDebugEnabled()) log.debug( "Marked transaction as rollback only because locks could not be acquired: " + tx); } else if (log.isDebugEnabled()) log.debug( "Transaction was not marked rollback-only while locks were not acquired: " + tx); } for (GridCacheEntryEx<K, V> e : entriesCopy()) { try { e.removeLock(lockVer); } catch (GridCacheEntryRemovedException ignored) { while (true) { try { e = cctx.cache().peekEx(e.key()); if (e != null) e.removeLock(lockVer); break; } catch (GridCacheEntryRemovedException ignore) { if (log.isDebugEnabled()) log.debug( "Attempted to remove lock on removed entry (will retry) [ver=" + lockVer + ", entry=" + e + ']'); } } } } } cctx.mvcc().recheckPendingLocks(); }
/** {@inheritDoc} */ @Override public void finishUnmarshal(GridCacheContext<K, V> ctx, ClassLoader ldr) throws GridException { super.finishUnmarshal(ctx, ldr); if (errBytes != null) err = ctx.marshaller().unmarshal(errBytes, ldr); metadata = unmarshalCollection(metaDataBytes, ctx, ldr); data = fields ? unmarshalFieldsCollection(dataBytes, ctx, ldr) : unmarshalCollection(dataBytes, ctx, ldr); }
/** {@inheritDoc} */ @Override public void prepareMarshal(GridCacheContext<K, V> ctx) throws GridException { super.prepareMarshal(ctx); if (map != null) { if (ctx.deploymentEnabled()) { for (K key : map.keySet()) prepareObject(key, ctx); } mapBytes = CU.marshal(ctx, map); } }
/** {@inheritDoc} */ @Override public GridFuture<Boolean> awaitAsync(final long timeout, final TimeUnit unit) { return ctx.closures() .callLocalSafe( new Callable<Boolean>() { @Override public Boolean call() throws Exception { return await(timeout, unit); } }, true); }
/** * Default constructor. * * @param name Sequence name. * @param key Sequence key. * @param seqView Sequence projection. * @param ctx CacheContext. * @param locVal Local counter. * @param upBound Upper bound. */ public GridCacheAtomicSequenceImpl( String name, GridCacheInternalStorableKey key, GridCacheProjection<GridCacheInternalStorableKey, GridCacheAtomicSequenceValue> seqView, GridCacheContext ctx, long locVal, long upBound) { assert key != null; assert seqView != null; assert ctx != null; assert locVal <= upBound; batchSize = ctx.config().getAtomicSequenceReserveSize(); this.ctx = ctx; this.key = key; this.seqView = seqView; this.upBound = upBound; this.locVal = locVal; this.name = name; log = ctx.gridConfig().getGridLogger().getLogger(getClass()); }
/** * @param ctx Cache context. * @param topic Topic for ordered messages. * @param prjPred Projection predicate. */ GridCacheContinuousQueryAdapter( GridCacheContext<K, V> ctx, Object topic, @Nullable GridPredicate<GridCacheEntry<K, V>> prjPred) { assert ctx != null; assert topic != null; this.ctx = ctx; this.topic = topic; this.prjPred = prjPred; log = ctx.logger(getClass()); }
/** {@inheritDoc} */ @Override public void close() throws GridException { closeLock.lock(); try { if (routineId == null) throw new IllegalStateException("Can't cancel query that was not executed."); ctx.kernalContext().continuous().stopRoutine(routineId).get(); } finally { closeLock.unlock(); } }
/** * @param cctx Registry. * @param keys Keys to lock. * @param tx Transaction. * @param read Read flag. * @param retval Flag to return value or not. * @param timeout Lock acquisition timeout. * @param filter Filter. */ public GridNearLockFuture( GridCacheContext<K, V> cctx, Collection<? extends K> keys, @Nullable GridNearTxLocal<K, V> tx, boolean read, boolean retval, long timeout, GridPredicate<GridCacheEntry<K, V>>[] filter) { super(cctx.kernalContext(), CU.boolReducer()); assert cctx != null; assert keys != null; this.cctx = cctx; this.keys = keys; this.tx = tx; this.read = read; this.retval = retval; this.timeout = timeout; this.filter = filter; threadId = tx == null ? Thread.currentThread().getId() : tx.threadId(); lockVer = tx != null ? tx.xidVersion() : cctx.versions().next(); futId = GridUuid.randomUuid(); entries = new ArrayList<>(keys.size()); log = U.logger(ctx, logRef, GridNearLockFuture.class); if (timeout > 0) { timeoutObj = new LockTimeoutObject(); cctx.time().addTimeoutObject(timeoutObj); } valMap = new ConcurrentHashMap8<>(keys.size(), 1f); }
/** * Acquires topology future and checks it completeness under the read lock. If it is not complete, * will asynchronously wait for it's completeness and then try again. */ void mapOnTopology() { // We must acquire topology snapshot from the topology version future. try { cctx.topology().readLock(); try { GridDhtTopologyFuture fut = cctx.topologyVersionFuture(); if (fut.isDone()) { GridDiscoveryTopologySnapshot snapshot = fut.topologySnapshot(); if (tx != null) { tx.topologyVersion(snapshot.topologyVersion()); tx.topologySnapshot(snapshot); } topSnapshot.compareAndSet(null, snapshot); map(keys); markInitialized(); } else { fut.listenAsync( new CI1<GridFuture<Long>>() { @Override public void apply(GridFuture<Long> t) { mapOnTopology(); } }); } } finally { cctx.topology().readUnlock(); } } catch (GridException e) { onDone(e); } }
/** {@inheritDoc} */ @Override public GridFuture<?> awaitAsync() { return ctx.closures() .callLocalSafe( new Callable<Object>() { @Nullable @Override public Object call() throws Exception { await(); return null; } }, true); }