Search in sources :

Example 16 with GridCacheReturn

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

the class GridDhtAtomicCache method updateWithBatch.

/**
     * Updates locked entries using batched write-through.
     *
     * @param node Sender 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 version.
     * @param dhtFut Optional DHT future.
     * @param replicate Whether replication is enabled.
     * @param taskName Task name.
     * @param expiry Expiry policy.
     * @param sndPrevVal If {@code true} sends previous value to backups.
     * @return Deleted entries.
     * @throws GridCacheEntryRemovedException Should not be thrown.
     */
@SuppressWarnings("unchecked")
private UpdateBatchResult updateWithBatch(final ClusterNode node, final boolean hasNear, final GridNearAtomicAbstractUpdateRequest req, final GridNearAtomicUpdateResponse res, final List<GridDhtCacheEntry> locked, final GridCacheVersion ver, @Nullable GridDhtAtomicAbstractUpdateFuture dhtFut, final boolean replicate, final String taskName, @Nullable final IgniteCacheExpiryPolicy expiry, final boolean sndPrevVal) throws GridCacheEntryRemovedException {
    // Cannot update in batches during DR due to possible conflicts.
    assert !ctx.dr().receiveEnabled();
    // Should not request return values for putAll.
    assert !req.returnValue() || req.operation() == TRANSFORM;
    if (!F.isEmpty(req.filter()) && ctx.loadPreviousValue()) {
        try {
            reloadIfNeeded(locked);
        } catch (IgniteCheckedException e) {
            res.addFailedKeys(req.keys(), e);
            return new UpdateBatchResult();
        }
    }
    int size = req.size();
    Map<KeyCacheObject, CacheObject> putMap = null;
    Map<KeyCacheObject, EntryProcessor<Object, Object, Object>> entryProcessorMap = null;
    Collection<KeyCacheObject> rmvKeys = null;
    List<CacheObject> writeVals = null;
    UpdateBatchResult updRes = new UpdateBatchResult();
    List<GridDhtCacheEntry> filtered = new ArrayList<>(size);
    GridCacheOperation op = req.operation();
    GridCacheReturn invokeRes = null;
    int firstEntryIdx = 0;
    boolean intercept = ctx.config().getInterceptor() != null;
    for (int i = 0; i < locked.size(); i++) {
        GridDhtCacheEntry entry = locked.get(i);
        try {
            if (!checkFilter(entry, req, res)) {
                if (expiry != null && entry.hasValue()) {
                    long ttl = expiry.forAccess();
                    if (ttl != CU.TTL_NOT_CHANGED) {
                        entry.updateTtl(null, ttl);
                        expiry.ttlUpdated(entry.key(), entry.version(), entry.readers());
                    }
                }
                if (log.isDebugEnabled())
                    log.debug("Entry did not pass the filter (will skip write) [entry=" + entry + ", filter=" + Arrays.toString(req.filter()) + ", res=" + res + ']');
                if (hasNear)
                    res.addSkippedIndex(i);
                firstEntryIdx++;
                continue;
            }
            if (op == TRANSFORM) {
                EntryProcessor<Object, Object, Object> entryProcessor = req.entryProcessor(i);
                CacheObject old = entry.innerGet(ver, null, /*read through*/
                true, /*metrics*/
                true, /*event*/
                true, req.subjectId(), entryProcessor, taskName, null, req.keepBinary());
                Object oldVal = null;
                Object updatedVal = null;
                CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry(entry.key(), old, entry.version(), req.keepBinary(), entry);
                CacheObject updated;
                try {
                    Object computed = entryProcessor.process(invokeEntry, req.invokeArguments());
                    if (computed != null) {
                        if (invokeRes == null)
                            invokeRes = new GridCacheReturn(node.isLocal());
                        computed = ctx.unwrapTemporary(computed);
                        invokeRes.addEntryProcessResult(ctx, entry.key(), invokeEntry.key(), computed, null, req.keepBinary());
                    }
                    if (!invokeEntry.modified())
                        continue;
                    updatedVal = ctx.unwrapTemporary(invokeEntry.getValue());
                    updated = ctx.toCacheObject(updatedVal);
                } catch (Exception e) {
                    if (invokeRes == null)
                        invokeRes = new GridCacheReturn(node.isLocal());
                    invokeRes.addEntryProcessResult(ctx, entry.key(), invokeEntry.key(), null, e, req.keepBinary());
                    updated = old;
                }
                if (updated == null) {
                    if (intercept) {
                        CacheLazyEntry e = new CacheLazyEntry(ctx, entry.key(), invokeEntry.key(), old, oldVal, req.keepBinary());
                        IgniteBiTuple<Boolean, ?> interceptorRes = ctx.config().getInterceptor().onBeforeRemove(e);
                        if (ctx.cancelRemove(interceptorRes))
                            continue;
                    }
                    // Update previous batch.
                    if (putMap != null) {
                        dhtFut = updatePartialBatch(hasNear, firstEntryIdx, filtered, ver, node, writeVals, putMap, null, entryProcessorMap, dhtFut, req, res, replicate, updRes, taskName, expiry, sndPrevVal);
                        firstEntryIdx = i;
                        putMap = null;
                        writeVals = null;
                        entryProcessorMap = null;
                        filtered = new ArrayList<>();
                    }
                    // Start collecting new batch.
                    if (rmvKeys == null)
                        rmvKeys = new ArrayList<>(size);
                    rmvKeys.add(entry.key());
                } else {
                    if (intercept) {
                        CacheLazyEntry e = new CacheLazyEntry(ctx, entry.key(), invokeEntry.key(), old, oldVal, req.keepBinary());
                        Object val = ctx.config().getInterceptor().onBeforePut(e, updatedVal);
                        if (val == null)
                            continue;
                        updated = ctx.toCacheObject(ctx.unwrapTemporary(val));
                    }
                    // Update previous batch.
                    if (rmvKeys != null) {
                        dhtFut = updatePartialBatch(hasNear, firstEntryIdx, filtered, ver, node, null, null, rmvKeys, entryProcessorMap, dhtFut, req, res, replicate, updRes, taskName, expiry, sndPrevVal);
                        firstEntryIdx = i;
                        rmvKeys = null;
                        entryProcessorMap = null;
                        filtered = new ArrayList<>();
                    }
                    if (putMap == null) {
                        putMap = new LinkedHashMap<>(size, 1.0f);
                        writeVals = new ArrayList<>(size);
                    }
                    putMap.put(entry.key(), updated);
                    writeVals.add(updated);
                }
                if (entryProcessorMap == null)
                    entryProcessorMap = new HashMap<>();
                entryProcessorMap.put(entry.key(), entryProcessor);
            } else if (op == UPDATE) {
                CacheObject updated = req.value(i);
                if (intercept) {
                    CacheObject old = entry.innerGet(null, null, /*read through*/
                    ctx.loadPreviousValue(), /*metrics*/
                    true, /*event*/
                    true, req.subjectId(), null, taskName, null, req.keepBinary());
                    Object val = ctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(ctx, entry.key(), old, req.keepBinary()), ctx.unwrapBinaryIfNeeded(updated, req.keepBinary(), false));
                    if (val == null)
                        continue;
                    updated = ctx.toCacheObject(ctx.unwrapTemporary(val));
                }
                assert updated != null;
                if (putMap == null) {
                    putMap = new LinkedHashMap<>(size, 1.0f);
                    writeVals = new ArrayList<>(size);
                }
                putMap.put(entry.key(), updated);
                writeVals.add(updated);
            } else {
                assert op == DELETE;
                if (intercept) {
                    CacheObject old = entry.innerGet(null, null, /*read through*/
                    ctx.loadPreviousValue(), /*metrics*/
                    true, /*event*/
                    true, req.subjectId(), null, taskName, null, req.keepBinary());
                    IgniteBiTuple<Boolean, ?> interceptorRes = ctx.config().getInterceptor().onBeforeRemove(new CacheLazyEntry(ctx, entry.key(), old, req.keepBinary()));
                    if (ctx.cancelRemove(interceptorRes))
                        continue;
                }
                if (rmvKeys == null)
                    rmvKeys = new ArrayList<>(size);
                rmvKeys.add(entry.key());
            }
            filtered.add(entry);
        } catch (IgniteCheckedException e) {
            res.addFailedKey(entry.key(), e);
        }
    }
    // Store final batch.
    if (putMap != null || rmvKeys != null) {
        dhtFut = updatePartialBatch(hasNear, firstEntryIdx, filtered, ver, node, writeVals, putMap, rmvKeys, entryProcessorMap, dhtFut, req, res, replicate, updRes, taskName, expiry, sndPrevVal);
    } else
        assert filtered.isEmpty();
    updRes.dhtFuture(dhtFut);
    updRes.invokeResult(invokeRes);
    return updRes;
}
Also used : CacheLazyEntry(org.apache.ignite.internal.processors.cache.CacheLazyEntry) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) 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) 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) NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) CacheStorePartialUpdateException(org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException) EntryProcessor(javax.cache.processor.EntryProcessor) GridDhtCacheEntry(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry) CacheInvokeEntry(org.apache.ignite.internal.processors.cache.CacheInvokeEntry) 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)

Example 17 with GridCacheReturn

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

the class GridDhtAtomicCache method processCheckUpdateRequest.

/**
     * @param nodeId Node ID.
     * @param checkReq Request.
     */
private void processCheckUpdateRequest(UUID nodeId, GridNearAtomicCheckUpdateRequest checkReq) {
    /*
         * Message is processed in the same stripe, so primary already processed update request. It is possible
         * response was not sent if operation result was empty. Near node will get original response or this one.
         */
    GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(ctx.cacheId(), nodeId, checkReq.futureId(), checkReq.partition(), false, false);
    GridCacheReturn ret = new GridCacheReturn(false, true);
    res.returnValue(ret);
    sendNearUpdateReply(nodeId, res);
}
Also used : GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn)

Example 18 with GridCacheReturn

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

the class GridNearAtomicUpdateFuture method onNodeLeft.

/** {@inheritDoc} */
@Override
public boolean onNodeLeft(UUID nodeId) {
    GridCacheReturn opRes0 = null;
    CachePartialUpdateCheckedException err0 = null;
    AffinityTopologyVersion remapTopVer0 = null;
    boolean rcvAll = false;
    List<GridNearAtomicCheckUpdateRequest> checkReqs = null;
    long futId;
    synchronized (this) {
        if (!futureMapped())
            return false;
        futId = this.futId;
        if (singleReq != null) {
            if (singleReq.req.nodeId.equals(nodeId)) {
                GridNearAtomicAbstractUpdateRequest req = singleReq.onPrimaryFail();
                if (req != null) {
                    rcvAll = true;
                    GridNearAtomicUpdateResponse res = primaryFailedResponse(req);
                    singleReq.onPrimaryResponse(res, cctx);
                    onPrimaryError(req, res);
                }
            } else {
                DhtLeftResult res = singleReq.onDhtNodeLeft(nodeId);
                if (res == DhtLeftResult.DONE)
                    rcvAll = true;
                else if (res == DhtLeftResult.ALL_RCVD_CHECK_PRIMARY)
                    checkReqs = Collections.singletonList(new GridNearAtomicCheckUpdateRequest(singleReq.req));
            }
            if (rcvAll) {
                opRes0 = opRes;
                err0 = err;
                remapTopVer0 = onAllReceived();
            }
        } else {
            if (mappings == null)
                return false;
            for (Map.Entry<UUID, PrimaryRequestState> e : mappings.entrySet()) {
                assert e.getKey().equals(e.getValue().req.nodeId());
                PrimaryRequestState reqState = e.getValue();
                boolean reqDone = false;
                if (e.getKey().equals(nodeId)) {
                    GridNearAtomicAbstractUpdateRequest req = reqState.onPrimaryFail();
                    if (req != null) {
                        reqDone = true;
                        GridNearAtomicUpdateResponse res = primaryFailedResponse(req);
                        reqState.onPrimaryResponse(res, cctx);
                        onPrimaryError(req, res);
                    }
                } else {
                    DhtLeftResult res = reqState.onDhtNodeLeft(nodeId);
                    if (res == DhtLeftResult.DONE)
                        reqDone = true;
                    else if (res == DhtLeftResult.ALL_RCVD_CHECK_PRIMARY) {
                        if (checkReqs == null)
                            checkReqs = new ArrayList<>();
                        checkReqs.add(new GridNearAtomicCheckUpdateRequest(reqState.req));
                    }
                }
                if (reqDone) {
                    assert mappings.size() > resCnt : "[mappings=" + mappings.size() + ", cnt=" + resCnt + ']';
                    resCnt++;
                    if (mappings.size() == resCnt) {
                        rcvAll = true;
                        opRes0 = opRes;
                        err0 = err;
                        remapTopVer0 = onAllReceived();
                        break;
                    }
                }
            }
        }
    }
    if (checkReqs != null) {
        assert !rcvAll;
        for (int i = 0; i < checkReqs.size(); i++) sendCheckUpdateRequest(checkReqs.get(i));
    } else if (rcvAll)
        finishUpdateFuture(opRes0, err0, remapTopVer0, futId);
    return false;
}
Also used : GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) CachePartialUpdateCheckedException(org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException) UUID(java.util.UUID) Map(java.util.Map)

Example 19 with GridCacheReturn

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

the class GridNearAtomicUpdateFuture method checkDhtNodes.

private void checkDhtNodes(long futId) {
    GridCacheReturn opRes0 = null;
    CachePartialUpdateCheckedException err0 = null;
    AffinityTopologyVersion remapTopVer0 = null;
    List<GridNearAtomicCheckUpdateRequest> checkReqs = null;
    boolean rcvAll = false;
    synchronized (this) {
        if (!checkFutureId(futId))
            return;
        if (singleReq != null) {
            if (!singleReq.req.initMappingLocally())
                return;
            DhtLeftResult res = singleReq.checkDhtNodes(cctx);
            if (res == DhtLeftResult.DONE) {
                opRes0 = opRes;
                err0 = err;
                remapTopVer0 = onAllReceived();
            } else if (res == DhtLeftResult.ALL_RCVD_CHECK_PRIMARY)
                checkReqs = Collections.singletonList(new GridNearAtomicCheckUpdateRequest(singleReq.req));
            else
                return;
        } else {
            if (mappings != null) {
                for (PrimaryRequestState reqState : mappings.values()) {
                    if (!reqState.req.initMappingLocally())
                        continue;
                    DhtLeftResult res = reqState.checkDhtNodes(cctx);
                    if (res == DhtLeftResult.DONE) {
                        assert mappings.size() > resCnt : "[mappings=" + mappings.size() + ", cnt=" + resCnt + ']';
                        resCnt++;
                        if (mappings.size() == resCnt) {
                            rcvAll = true;
                            opRes0 = opRes;
                            err0 = err;
                            remapTopVer0 = onAllReceived();
                            break;
                        }
                    } else if (res == DhtLeftResult.ALL_RCVD_CHECK_PRIMARY) {
                        if (checkReqs == null)
                            checkReqs = new ArrayList<>(mappings.size());
                        checkReqs.add(new GridNearAtomicCheckUpdateRequest(reqState.req));
                    }
                }
            } else
                return;
        }
    }
    if (checkReqs != null) {
        assert !rcvAll;
        for (int i = 0; i < checkReqs.size(); i++) sendCheckUpdateRequest(checkReqs.get(i));
    } else if (rcvAll)
        finishUpdateFuture(opRes0, err0, remapTopVer0, futId);
}
Also used : GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) CachePartialUpdateCheckedException(org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException)

Example 20 with GridCacheReturn

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

the class GridNearAtomicUpdateFuture method sendUpdateRequests.

/**
     * Sends messages to remote nodes and updates local cache.
     *
     * @param mappings Mappings to send.
     */
private void sendUpdateRequests(Map<UUID, PrimaryRequestState> mappings) {
    UUID locNodeId = cctx.localNodeId();
    GridNearAtomicAbstractUpdateRequest locUpdate = null;
    // Send messages to remote nodes first, then run local update.
    for (PrimaryRequestState reqState : mappings.values()) {
        GridNearAtomicAbstractUpdateRequest req = reqState.req;
        if (locNodeId.equals(req.nodeId())) {
            assert locUpdate == null : "Cannot have more than one local mapping [locUpdate=" + locUpdate + ", req=" + req + ']';
            locUpdate = req;
        } else {
            try {
                if (req.initMappingLocally() && reqState.dhtNodes.isEmpty()) {
                    reqState.dhtNodes = null;
                    req.needPrimaryResponse(true);
                }
                cctx.io().send(req.nodeId(), req, cctx.ioPolicy());
                if (msgLog.isDebugEnabled()) {
                    msgLog.debug("Near update fut, sent request [futId=" + req.futureId() + ", node=" + req.nodeId() + ']');
                }
            } catch (IgniteCheckedException e) {
                if (msgLog.isDebugEnabled()) {
                    msgLog.debug("Near update fut, failed to send request [futId=" + req.futureId() + ", node=" + req.nodeId() + ", err=" + e + ']');
                }
                onSendError(req, e);
            }
        }
    }
    if (locUpdate != null) {
        cache.updateAllAsyncInternal(cctx.localNodeId(), locUpdate, new GridDhtAtomicCache.UpdateReplyClosure() {

            @Override
            public void apply(GridNearAtomicAbstractUpdateRequest req, GridNearAtomicUpdateResponse res) {
                if (syncMode != FULL_ASYNC)
                    onPrimaryResponse(res.nodeId(), res, false);
                else if (res.remapTopologyVersion() != null)
                    ((GridDhtAtomicCache) cctx.cache()).remapToNewPrimary(req);
            }
        });
    }
    if (syncMode == FULL_ASYNC)
        completeFuture(new GridCacheReturn(cctx, true, true, null, true), null, null);
}
Also used : IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheReturn(org.apache.ignite.internal.processors.cache.GridCacheReturn) UUID(java.util.UUID)

Aggregations

GridCacheReturn (org.apache.ignite.internal.processors.cache.GridCacheReturn)27 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)18 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)12 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)12 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)11 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)11 CachePartialUpdateCheckedException (org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException)11 ArrayList (java.util.ArrayList)7 UUID (java.util.UUID)7 NodeStoppingException (org.apache.ignite.internal.NodeStoppingException)7 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)7 Map (java.util.Map)6 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)6 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)5 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)5 HashMap (java.util.HashMap)4 LinkedHashMap (java.util.LinkedHashMap)4 GridCacheOperation (org.apache.ignite.internal.processors.cache.GridCacheOperation)4 GridDhtCacheEntry (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry)4 GridDhtInvalidPartitionException (org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException)4