Search in sources :

Example 6 with GridCacheUpdateAtomicResult

use of org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult in project ignite by apache.

the class GridDhtAtomicCache method updateSingle.

/**
 * Updates locked entries one-by-one.
 *
 * @param nearNode Originating node.
 * @param hasNear {@code True} if originating node has near cache.
 * @param req Update request.
 * @param res Update response.
 * @param locked Locked entries.
 * @param ver Assigned update version.
 * @param dhtFut Optional DHT future.
 * @param replicate Whether DR is enabled for that cache.
 * @param taskName Task name.
 * @param expiry Expiry policy.
 * @param sndPrevVal If {@code true} sends previous value to backups.
 * @return Return value.
 * @throws GridCacheEntryRemovedException Should be never thrown.
 */
private DhtAtomicUpdateResult updateSingle(ClusterNode nearNode, boolean hasNear, GridNearAtomicAbstractUpdateRequest req, GridNearAtomicUpdateResponse res, List<GridDhtCacheEntry> locked, GridCacheVersion ver, @Nullable GridDhtAtomicAbstractUpdateFuture dhtFut, boolean replicate, String taskName, @Nullable IgniteCacheExpiryPolicy expiry, boolean sndPrevVal) throws GridCacheEntryRemovedException {
    GridCacheReturn retVal = null;
    Collection<IgniteBiTuple<GridDhtCacheEntry, GridCacheVersion>> deleted = null;
    AffinityTopologyVersion topVer = req.topologyVersion();
    boolean intercept = ctx.config().getInterceptor() != null;
    AffinityAssignment affAssignment = ctx.affinity().assignment(topVer);
    // Avoid iterator creation.
    for (int i = 0; i < req.size(); i++) {
        KeyCacheObject k = req.key(i);
        GridCacheOperation op = req.operation();
        // No GridCacheEntryRemovedException can be thrown.
        try {
            GridDhtCacheEntry entry = locked.get(i);
            GridCacheVersion newConflictVer = req.conflictVersion(i);
            long newConflictTtl = req.conflictTtl(i);
            long newConflictExpireTime = req.conflictExpireTime(i);
            assert !(newConflictVer instanceof GridCacheVersionEx) : newConflictVer;
            Object writeVal = op == TRANSFORM ? req.entryProcessor(i) : req.writeValue(i);
            // Get readers before innerUpdate (reader cleared after remove).
            GridDhtCacheEntry.ReaderId[] readers = entry.readersLocked();
            GridCacheUpdateAtomicResult updRes = entry.innerUpdate(ver, nearNode.id(), locNodeId, op, writeVal, req.invokeArguments(), writeThrough() && !req.skipStore(), !req.skipStore(), sndPrevVal || req.returnValue(), req.keepBinary(), expiry, /*event*/
            true, /*metrics*/
            true, /*primary*/
            true, /*verCheck*/
            false, topVer, req.filter(), replicate ? DR_PRIMARY : DR_NONE, newConflictTtl, newConflictExpireTime, newConflictVer, /*conflictResolve*/
            true, intercept, req.subjectId(), taskName, /*prevVal*/
            null, /*updateCntr*/
            null, dhtFut);
            if (dhtFut != null) {
                if (updRes.sendToDht()) {
                    // Send to backups even in case of remove-remove scenarios.
                    GridCacheVersionConflictContext<?, ?> conflictCtx = updRes.conflictResolveResult();
                    if (conflictCtx == null)
                        newConflictVer = null;
                    else if (conflictCtx.isMerge())
                        // Conflict version is discarded in case of merge.
                        newConflictVer = null;
                    EntryProcessor<Object, Object, Object> entryProcessor = null;
                    dhtFut.addWriteEntry(affAssignment, entry, updRes.newValue(), entryProcessor, updRes.newTtl(), updRes.conflictExpireTime(), newConflictVer, sndPrevVal, updRes.oldValue(), updRes.updateCounter());
                    if (readers != null)
                        dhtFut.addNearWriteEntries(nearNode, readers, entry, updRes.newValue(), entryProcessor, updRes.newTtl(), updRes.conflictExpireTime());
                } else {
                    if (log.isDebugEnabled())
                        log.debug("Entry did not pass the filter or conflict resolution (will skip write) " + "[entry=" + entry + ", filter=" + Arrays.toString(req.filter()) + ']');
                }
            }
            if (hasNear) {
                if (updRes.sendToDht()) {
                    if (!ctx.affinity().partitionBelongs(nearNode, entry.partition(), topVer)) {
                        // If put the same value as in request then do not need to send it back.
                        if (op == TRANSFORM || writeVal != updRes.newValue()) {
                            res.addNearValue(i, updRes.newValue(), updRes.newTtl(), updRes.conflictExpireTime());
                        } else
                            res.addNearTtl(i, updRes.newTtl(), updRes.conflictExpireTime());
                        if (updRes.newValue() != null) {
                            IgniteInternalFuture<Boolean> f = entry.addReader(nearNode.id(), req.messageId(), topVer);
                            assert f == null : f;
                        }
                    } else if (GridDhtCacheEntry.ReaderId.contains(readers, nearNode.id())) {
                        // Reader became primary or backup.
                        entry.removeReader(nearNode.id(), req.messageId());
                    } else
                        res.addSkippedIndex(i);
                } else
                    res.addSkippedIndex(i);
            }
            if (updRes.removeVersion() != null) {
                if (deleted == null)
                    deleted = new ArrayList<>(req.size());
                deleted.add(F.t(entry, updRes.removeVersion()));
            }
            if (op == TRANSFORM) {
                assert !req.returnValue();
                IgniteBiTuple<Object, Exception> compRes = updRes.computedResult();
                if (compRes != null && (compRes.get1() != null || compRes.get2() != null)) {
                    if (retVal == null)
                        retVal = new GridCacheReturn(nearNode.isLocal());
                    retVal.addEntryProcessResult(ctx, k, null, compRes.get1(), compRes.get2(), req.keepBinary());
                }
            } else {
                // Create only once.
                if (retVal == null) {
                    CacheObject ret = updRes.oldValue();
                    retVal = new GridCacheReturn(ctx, nearNode.isLocal(), req.keepBinary(), req.returnValue() ? ret : null, updRes.success());
                }
            }
        } catch (IgniteCheckedException e) {
            res.addFailedKey(k, e);
        }
    }
    return new DhtAtomicUpdateResult(retVal, deleted, dhtFut);
}
Also used : AffinityAssignment(org.apache.ignite.internal.processors.affinity.AffinityAssignment) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) ArrayList(java.util.ArrayList) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) StorageException(org.apache.ignite.internal.pagemem.wal.StorageException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) IgniteOutOfMemoryException(org.apache.ignite.internal.mem.IgniteOutOfMemoryException) NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) CacheStoppedException(org.apache.ignite.internal.processors.cache.CacheStoppedException) CacheStorePartialUpdateException(org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException) GridCacheVersionEx(org.apache.ignite.internal.processors.cache.version.GridCacheVersionEx) GridDhtCacheEntry(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridTimeoutObject(org.apache.ignite.internal.processors.timeout.GridTimeoutObject) GridCacheOperation(org.apache.ignite.internal.processors.cache.GridCacheOperation) GridCacheUpdateAtomicResult(org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult)

Example 7 with GridCacheUpdateAtomicResult

use of org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult in project ignite by apache.

the class GridDhtAtomicCache method processDhtAtomicUpdateRequest.

/**
 * @param nodeId Sender node ID.
 * @param req Dht atomic update request.
 */
private void processDhtAtomicUpdateRequest(UUID nodeId, GridDhtAtomicAbstractUpdateRequest req) {
    assert Thread.currentThread().getName().startsWith("sys-stripe-") : Thread.currentThread().getName();
    if (msgLog.isDebugEnabled()) {
        msgLog.debug("Received DHT atomic update request [futId=" + req.futureId() + ", writeVer=" + req.writeVersion() + ", node=" + nodeId + ']');
    }
    assert req.partition() >= 0 : req;
    GridCacheVersion ver = req.writeVersion();
    ctx.versions().onReceived(nodeId, ver);
    GridDhtAtomicNearResponse nearRes = null;
    if (req.nearNodeId() != null) {
        nearRes = new GridDhtAtomicNearResponse(ctx.cacheId(), req.partition(), req.nearFutureId(), nodeId, req.flags());
    }
    boolean replicate = ctx.isDrEnabled();
    boolean intercept = req.forceTransformBackups() && ctx.config().getInterceptor() != null;
    boolean needTaskName = ctx.events().isRecordable(EVT_CACHE_OBJECT_READ) || ctx.events().isRecordable(EVT_CACHE_OBJECT_PUT) || ctx.events().isRecordable(EVT_CACHE_OBJECT_REMOVED);
    String taskName = needTaskName ? ctx.kernalContext().task().resolveTaskName(req.taskNameHash()) : null;
    ctx.shared().database().checkpointReadLock();
    try {
        for (int i = 0; i < req.size(); i++) {
            KeyCacheObject key = req.key(i);
            try {
                while (true) {
                    GridDhtCacheEntry entry = null;
                    try {
                        entry = entryExx(key);
                        CacheObject val = req.value(i);
                        CacheObject prevVal = req.previousValue(i);
                        EntryProcessor<Object, Object, Object> entryProcessor = req.entryProcessor(i);
                        Long updateIdx = req.updateCounter(i);
                        GridCacheOperation op = entryProcessor != null ? TRANSFORM : (val != null) ? UPDATE : DELETE;
                        long ttl = req.ttl(i);
                        long expireTime = req.conflictExpireTime(i);
                        GridCacheUpdateAtomicResult updRes = entry.innerUpdate(ver, nodeId, nodeId, op, op == TRANSFORM ? entryProcessor : val, op == TRANSFORM ? req.invokeArguments() : null, /*write-through*/
                        (ctx.store().isLocal() && !ctx.shared().localStorePrimaryOnly()) && writeThrough() && !req.skipStore(), /*read-through*/
                        false, /*retval*/
                        false, req.keepBinary(), /*expiry policy*/
                        null, /*event*/
                        true, /*metrics*/
                        true, /*primary*/
                        false, /*check version*/
                        !req.forceTransformBackups(), req.topologyVersion(), CU.empty0(), replicate ? DR_BACKUP : DR_NONE, ttl, expireTime, req.conflictVersion(i), false, intercept, taskName, prevVal, updateIdx, null, req.transformOperation());
                        if (updRes.removeVersion() != null)
                            ctx.onDeferredDelete(entry, updRes.removeVersion());
                        entry.onUnlock();
                        // While.
                        break;
                    } catch (GridCacheEntryRemovedException ignored) {
                        if (log.isDebugEnabled())
                            log.debug("Got removed entry while updating backup value (will retry): " + key);
                        entry = null;
                    } finally {
                        if (entry != null)
                            entry.touch();
                    }
                }
            } catch (NodeStoppingException e) {
                U.warn(log, "Failed to update key on backup (local node is stopping): " + key);
                return;
            } catch (GridDhtInvalidPartitionException ignored) {
            // Ignore.
            } catch (IgniteCheckedException | RuntimeException e) {
                if (e instanceof RuntimeException && !X.hasCause(e, IgniteOutOfMemoryException.class))
                    throw (RuntimeException) e;
                IgniteCheckedException err = new IgniteCheckedException("Failed to update key on backup node: " + key, e);
                if (nearRes != null)
                    nearRes.addFailedKey(key, err);
                U.error(log, "Failed to update key on backup node: " + key, e);
            }
        }
    } finally {
        ctx.shared().database().checkpointReadUnlock();
    }
    GridDhtAtomicUpdateResponse dhtRes = null;
    if (req.nearSize() > 0 || req.obsoleteNearKeysSize() > 0) {
        List<KeyCacheObject> nearEvicted = null;
        if (isNearEnabled(ctx))
            nearEvicted = ((GridNearAtomicCache<K, V>) near()).processDhtAtomicUpdateRequest(nodeId, req, nearRes);
        else if (req.nearSize() > 0) {
            nearEvicted = new ArrayList<>(req.nearSize());
            for (int i = 0; i < req.nearSize(); i++) nearEvicted.add(req.nearKey(i));
        }
        if (nearEvicted != null) {
            dhtRes = new GridDhtAtomicUpdateResponse(ctx.cacheId(), req.partition(), req.futureId(), ctx.deploymentEnabled());
            dhtRes.nearEvicted(nearEvicted);
        }
    }
    try {
        // TODO fire events only after successful fsync
        if (ctx.shared().wal() != null)
            ctx.shared().wal().flush(null, false);
    } catch (StorageException e) {
        if (dhtRes != null)
            dhtRes.onError(new IgniteCheckedException(e));
        if (nearRes != null)
            nearRes.onClassError(e);
    } catch (IgniteCheckedException e) {
        if (dhtRes != null)
            dhtRes.onError(e);
        if (nearRes != null)
            nearRes.onClassError(e);
    }
    if (nearRes != null)
        sendDhtNearResponse(req, nearRes);
    if (dhtRes == null && req.replyWithoutDelay()) {
        dhtRes = new GridDhtAtomicUpdateResponse(ctx.cacheId(), req.partition(), req.futureId(), ctx.deploymentEnabled());
    }
    if (dhtRes != null)
        sendDhtPrimaryResponse(nodeId, req, dhtRes);
    else
        sendDeferredUpdateResponse(req.partition(), nodeId, req.futureId());
}
Also used : NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) ArrayList(java.util.ArrayList) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridNearAtomicCache(org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException) IgniteOutOfMemoryException(org.apache.ignite.internal.mem.IgniteOutOfMemoryException) GridDhtCacheEntry(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridTimeoutObject(org.apache.ignite.internal.processors.timeout.GridTimeoutObject) GridCacheOperation(org.apache.ignite.internal.processors.cache.GridCacheOperation) GridCacheUpdateAtomicResult(org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult) StorageException(org.apache.ignite.internal.processors.cache.persistence.StorageException)

Example 8 with GridCacheUpdateAtomicResult

use of org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult in project ignite by apache.

the class GridNearAtomicCache method processDhtAtomicUpdateRequest.

/**
 * @param nodeId Sender node ID.
 * @param req Dht atomic update request.
 * @param res Dht atomic update response.
 * @return Evicted near keys (if any).
 */
@Nullable
public List<KeyCacheObject> processDhtAtomicUpdateRequest(UUID nodeId, GridDhtAtomicAbstractUpdateRequest req, GridDhtAtomicNearResponse res) {
    GridCacheVersion ver = req.writeVersion();
    assert ver != null;
    boolean intercept = req.forceTransformBackups() && ctx.config().getInterceptor() != null;
    boolean needTaskName = ctx.events().isRecordable(EVT_CACHE_OBJECT_READ) || ctx.events().isRecordable(EVT_CACHE_OBJECT_PUT) || ctx.events().isRecordable(EVT_CACHE_OBJECT_REMOVED);
    String taskName = needTaskName ? ctx.kernalContext().task().resolveTaskName(req.taskNameHash()) : null;
    List<KeyCacheObject> nearEvicted = null;
    for (int i = 0; i < req.nearSize(); i++) {
        KeyCacheObject key = req.nearKey(i);
        try {
            while (true) {
                try {
                    GridCacheEntryEx entry = peekEx(key);
                    if (entry == null) {
                        if (nearEvicted == null)
                            nearEvicted = new ArrayList<>();
                        nearEvicted.add(key);
                        break;
                    }
                    CacheObject val = req.nearValue(i);
                    EntryProcessor<Object, Object, Object> entryProcessor = req.nearEntryProcessor(i);
                    GridCacheOperation op = entryProcessor != null ? TRANSFORM : (val != null) ? UPDATE : DELETE;
                    long ttl = req.nearTtl(i);
                    long expireTime = req.nearExpireTime(i);
                    GridCacheUpdateAtomicResult updRes = entry.innerUpdate(ver, nodeId, nodeId, op, op == TRANSFORM ? entryProcessor : val, op == TRANSFORM ? req.invokeArguments() : null, /*write-through*/
                    false, /*read-through*/
                    false, /*retval*/
                    false, req.keepBinary(), null, /*event*/
                    true, /*metrics*/
                    true, /*primary*/
                    false, /*check version*/
                    !req.forceTransformBackups(), req.topologyVersion(), CU.empty0(), DR_NONE, ttl, expireTime, null, false, intercept, taskName, null, null, null, false);
                    if (updRes.removeVersion() != null)
                        ctx.onDeferredDelete(entry, updRes.removeVersion());
                    break;
                } catch (GridCacheEntryRemovedException ignored) {
                    if (log.isDebugEnabled())
                        log.debug("Got removed entry while updating near value (will retry): " + key);
                }
            }
        } catch (IgniteCheckedException e) {
            res.addFailedKey(key, new IgniteCheckedException("Failed to update near cache key: " + key, e));
        }
    }
    for (int i = 0; i < req.obsoleteNearKeysSize(); i++) {
        KeyCacheObject key = req.obsoleteNearKey(i);
        GridCacheEntryEx entry = peekEx(key);
        if (entry != null && entry.markObsolete(ver))
            removeEntry(entry);
    }
    return nearEvicted;
}
Also used : ArrayList(java.util.ArrayList) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridCacheOperation(org.apache.ignite.internal.processors.cache.GridCacheOperation) GridCacheUpdateAtomicResult(org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)8 GridCacheOperation (org.apache.ignite.internal.processors.cache.GridCacheOperation)8 GridCacheUpdateAtomicResult (org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult)8 ArrayList (java.util.ArrayList)7 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)7 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)7 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)7 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)6 GridDhtCacheEntry (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry)6 GridTimeoutObject (org.apache.ignite.internal.processors.timeout.GridTimeoutObject)6 AffinityAssignment (org.apache.ignite.internal.processors.affinity.AffinityAssignment)5 CacheStorePartialUpdateException (org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException)5 IgniteBiTuple (org.apache.ignite.lang.IgniteBiTuple)5 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)4 Nullable (org.jetbrains.annotations.Nullable)4 NodeStoppingException (org.apache.ignite.internal.NodeStoppingException)3 IgniteOutOfMemoryException (org.apache.ignite.internal.mem.IgniteOutOfMemoryException)3 CacheLazyEntry (org.apache.ignite.internal.processors.cache.CacheLazyEntry)3 GridDhtInvalidPartitionException (org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException)3 IgniteException (org.apache.ignite.IgniteException)2