/** * @param cctx Cache context. * @param completionCb Callback to invoke when future is completed. * @param writeVer Write version. * @param updateReq Update request. * @param updateRes Update response. */ public GridDhtAtomicUpdateFuture( GridCacheContext cctx, CI2<GridNearAtomicUpdateRequest, GridNearAtomicUpdateResponse> completionCb, GridCacheVersion writeVer, GridNearAtomicUpdateRequest updateReq, GridNearAtomicUpdateResponse updateRes) { this.cctx = cctx; this.writeVer = writeVer; futVer = cctx.versions().next(updateReq.topologyVersion()); this.updateReq = updateReq; this.completionCb = completionCb; this.updateRes = updateRes; if (log == null) log = U.logger(cctx.kernalContext(), logRef, GridDhtAtomicUpdateFuture.class); keys = new ArrayList<>(updateReq.keys().size()); mappings = U.newHashMap(updateReq.keys().size()); boolean topLocked = updateReq.topologyLocked() || (updateReq.fastMap() && !updateReq.clientRequest()); waitForExchange = !topLocked; }
/** * @param req Update request. * @param res Update response. */ public void processNearAtomicUpdateResponse( GridNearAtomicUpdateRequest req, GridNearAtomicUpdateResponse res) { if (F.size(res.failedKeys()) == req.keys().size()) return; /* * Choose value to be stored in near cache: first check key is not in failed and not in skipped list, * then check if value was generated on primary node, if not then use value sent in request. */ Collection<KeyCacheObject> failed = res.failedKeys(); List<Integer> nearValsIdxs = res.nearValuesIndexes(); List<Integer> skipped = res.skippedIndexes(); GridCacheVersion ver = req.updateVersion(); if (ver == null) ver = res.nearVersion(); assert ver != null : "Failed to find version [req=" + req + ", res=" + res + ']'; int nearValIdx = 0; String taskName = ctx.kernalContext().task().resolveTaskName(req.taskNameHash()); for (int i = 0; i < req.keys().size(); i++) { if (F.contains(skipped, i)) continue; KeyCacheObject key = req.keys().get(i); if (F.contains(failed, key)) continue; if (ctx.affinity() .belongs( ctx.localNode(), ctx.affinity().partition(key), req.topologyVersion())) { // Reader became backup. GridCacheEntryEx entry = peekEx(key); if (entry != null && entry.markObsolete(ver)) removeEntry(entry); continue; } CacheObject val = null; if (F.contains(nearValsIdxs, i)) { val = res.nearValue(nearValIdx); nearValIdx++; } else { assert req.operation() != TRANSFORM; if (req.operation() != DELETE) val = req.value(i); } long ttl = res.nearTtl(i); long expireTime = res.nearExpireTime(i); if (ttl != CU.TTL_NOT_CHANGED && expireTime == CU.EXPIRE_TIME_CALCULATE) expireTime = CU.toExpireTime(ttl); try { processNearAtomicUpdateResponse( ver, key, val, null, ttl, expireTime, req.keepBinary(), req.nodeId(), req.subjectId(), taskName); } catch (IgniteCheckedException e) { res.addFailedKey( key, new IgniteCheckedException("Failed to update key in near cache: " + key, e)); } } }