Search in sources :

Example 71 with GridFutureAdapter

use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.

the class GridCacheMapEntry method mvccSet.

/**
 * {@inheritDoc}
 */
@Override
public final GridCacheUpdateTxResult mvccSet(IgniteInternalTx tx, UUID affNodeId, CacheObject val, EntryProcessor entryProc, Object[] invokeArgs, long ttl0, AffinityTopologyVersion topVer, MvccSnapshot mvccVer, GridCacheOperation op, boolean needHistory, boolean noCreate, boolean needOldVal, CacheEntryPredicate filter, boolean retVal, boolean keepBinary) throws IgniteCheckedException, GridCacheEntryRemovedException {
    assert tx != null;
    final boolean valid = valid(tx.topologyVersion());
    final boolean invoke = entryProc != null;
    final GridCacheVersion newVer;
    WALPointer logPtr = null;
    ensureFreeSpace();
    lockEntry();
    MvccUpdateResult res;
    try {
        checkObsolete();
        newVer = tx.writeVersion();
        assert newVer != null : "Failed to get write version for tx: " + tx;
        // Determine new ttl and expire time.
        long expireTime, ttl = ttl0;
        if (ttl == -1L) {
            ttl = ttlExtras();
            expireTime = expireTimeExtras();
        } else
            expireTime = CU.toExpireTime(ttl);
        assert ttl >= 0 : ttl;
        assert expireTime >= 0 : expireTime;
        // Detach value before index update.
        val = cctx.kernalContext().cacheObjects().prepareForCache(val, cctx);
        assert val != null || invoke;
        res = cctx.offheap().mvccUpdate(this, val, newVer, expireTime, mvccVer, tx.local(), needHistory, noCreate, needOldVal, filter, retVal, keepBinary, entryProc, invokeArgs);
        assert res != null;
        // updating the key which just has been rebalanced.
        assert res.resultType() != ResultType.VERSION_FOUND || op == CREATE && tx.local() || !tx.local();
        // PREV_NOT_NULL on CREATE is possible only on primary.
        assert res.resultType() != ResultType.PREV_NOT_NULL || op != CREATE || tx.local();
        if (res.resultType() == ResultType.VERSION_MISMATCH)
            throw serializationError();
        else if (res.resultType() == ResultType.FILTERED) {
            GridCacheUpdateTxResult updRes = new GridCacheUpdateTxResult(invoke);
            assert !invoke || res.invokeResult() != null;
            if (// No-op invoke happened.
            invoke)
                updRes.invokeResult(res.invokeResult());
            updRes.filtered(true);
            if (retVal)
                updRes.prevValue(res.oldValue());
            return updRes;
        } else if (noCreate && !invoke && res.resultType() == ResultType.PREV_NULL)
            return new GridCacheUpdateTxResult(false);
        else if (res.resultType() == ResultType.LOCKED) {
            unlockEntry();
            MvccVersion lockVer = res.resultVersion();
            GridFutureAdapter<GridCacheUpdateTxResult> resFut = new GridFutureAdapter<>();
            IgniteInternalFuture<?> lockFut = cctx.kernalContext().coordinators().waitForLock(cctx, mvccVer, lockVer);
            lockFut.listen(new MvccUpdateLockListener(tx, this, affNodeId, topVer, val, ttl0, mvccVer, op, needHistory, noCreate, resFut, needOldVal, filter, retVal, keepBinary, entryProc, invokeArgs));
            return new GridCacheUpdateTxResult(false, resFut);
        } else if (op == CREATE && tx.local() && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.VERSION_FOUND))
            throw new IgniteTxDuplicateKeyCheckedException("Duplicate key during INSERT [key=" + key + ']');
        if (cctx.deferredDelete() && deletedUnlocked() && !detached())
            deletedUnlocked(false);
        if (res.resultType() == ResultType.PREV_NULL) {
            TxCounters counters = tx.txCounters(true);
            if (compareIgnoreOpCounter(res.resultVersion(), mvccVer) == 0) {
                if (res.isKeyAbsentBefore())
                    counters.incrementUpdateCounter(cctx.cacheId(), partition());
            } else
                counters.incrementUpdateCounter(cctx.cacheId(), partition());
            counters.accumulateSizeDelta(cctx.cacheId(), partition(), 1);
        } else if (res.resultType() == ResultType.PREV_NOT_NULL && compareIgnoreOpCounter(res.resultVersion(), mvccVer) != 0) {
            TxCounters counters = tx.txCounters(true);
            counters.incrementUpdateCounter(cctx.cacheId(), partition());
        } else if (res.resultType() == ResultType.REMOVED_NOT_NULL) {
            TxCounters counters = tx.txCounters(true);
            if (compareIgnoreOpCounter(res.resultVersion(), mvccVer) == 0) {
                if (// Do not count own update removal.
                res.isKeyAbsentBefore())
                    counters.decrementUpdateCounter(cctx.cacheId(), partition());
            } else
                counters.incrementUpdateCounter(cctx.cacheId(), partition());
            counters.accumulateSizeDelta(cctx.cacheId(), partition(), -1);
        }
        if (cctx.group().persistenceEnabled() && cctx.group().walEnabled()) {
            logPtr = cctx.shared().wal().log(new MvccDataRecord(new MvccDataEntry(cctx.cacheId(), key, val, res.resultType() == ResultType.PREV_NULL ? CREATE : (res.resultType() == ResultType.REMOVED_NOT_NULL) ? DELETE : UPDATE, tx.nearXidVersion(), newVer, expireTime, key.partition(), 0L, mvccVer)));
        }
        update(val, expireTime, ttl, newVer, true);
        recordNodeId(affNodeId, topVer);
    } finally {
        if (lockedByCurrentThread()) {
            unlockEntry();
            cctx.evicts().touch(this);
        }
    }
    onUpdateFinished(0L);
    GridCacheUpdateTxResult updRes = valid ? new GridCacheUpdateTxResult(true, 0L, logPtr) : new GridCacheUpdateTxResult(false, logPtr);
    if (retVal && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.VERSION_FOUND))
        updRes.prevValue(res.oldValue());
    if (needOldVal && compareIgnoreOpCounter(res.resultVersion(), mvccVer) != 0 && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.REMOVED_NOT_NULL))
        updRes.oldValue(res.oldValue());
    updRes.newValue(res.newValue());
    if (invoke && res.resultType() != ResultType.VERSION_FOUND) {
        assert res.invokeResult() != null;
        updRes.invokeResult(res.invokeResult());
    }
    updRes.mvccHistory(res.history());
    return updRes;
}
Also used : TxCounters(org.apache.ignite.internal.processors.cache.transactions.TxCounters) MvccUpdateResult(org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccUpdateResult) MvccDataEntry(org.apache.ignite.internal.pagemem.wal.record.MvccDataEntry) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteTxDuplicateKeyCheckedException(org.apache.ignite.internal.transactions.IgniteTxDuplicateKeyCheckedException) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) MvccVersion(org.apache.ignite.internal.processors.cache.mvcc.MvccVersion) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) MvccDataRecord(org.apache.ignite.internal.pagemem.wal.record.MvccDataRecord) WALPointer(org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer)

Example 72 with GridFutureAdapter

use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.

the class GridEventStorageManager method remoteEventsAsync.

/**
 * @param p Grid event predicate.
 * @param nodes Collection of nodes.
 * @param timeout Maximum time to wait for result, if {@code 0}, then wait until result is received.
 * @return Collection of events.
 */
public <T extends Event> IgniteInternalFuture<List<T>> remoteEventsAsync(final IgnitePredicate<T> p, final Collection<? extends ClusterNode> nodes, final long timeout) {
    assert p != null;
    assert nodes != null;
    final GridFutureAdapter<List<T>> fut = new GridFutureAdapter<>();
    ctx.closure().runLocalSafe(new GPR() {

        @Override
        public void run() {
            try {
                fut.onDone(query(p, nodes, timeout));
            } catch (IgniteCheckedException e) {
                fut.onDone(e);
            }
        }
    }, true);
    return fut;
}
Also used : IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) GPR(org.apache.ignite.internal.util.typedef.internal.GPR) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList)

Example 73 with GridFutureAdapter

use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.

the class IndexesRebuildTask method rebuild.

/**
 * Start to rebuild.
 *
 * @param cctx Cache context.
 * @param force Force rebuild indexes.
 * @return A future of rebuilding cache indexes.
 */
@Nullable
public IgniteInternalFuture<?> rebuild(GridCacheContext<?, ?> cctx, boolean force, IndexRebuildCancelToken cancelTok) {
    assert cctx != null;
    if (!CU.affinityNode(cctx.localNode(), cctx.config().getNodeFilter()))
        return null;
    IgnitePageStoreManager pageStore = cctx.shared().pageStore();
    SchemaIndexCacheVisitorClosure clo;
    String cacheName = cctx.name();
    if (pageStore == null || !pageStore.hasIndexStore(cctx.groupId())) {
        boolean mvccEnabled = cctx.mvccEnabled();
        // If there are no index store, rebuild all indexes.
        clo = row -> cctx.queries().store(row, null, mvccEnabled);
    } else {
        Collection<InlineIndex> toRebuild = cctx.kernalContext().indexProcessor().treeIndexes(cctx, !force);
        if (F.isEmpty(toRebuild))
            return null;
        clo = row -> cctx.kernalContext().indexProcessor().store(toRebuild, row, null, false);
    }
    // Closure prepared, do rebuild.
    cctx.kernalContext().query().markAsRebuildNeeded(cctx, true);
    GridFutureAdapter<Void> rebuildCacheIdxFut = new GridFutureAdapter<>();
    // To avoid possible data race.
    GridFutureAdapter<Void> outRebuildCacheIdxFut = new GridFutureAdapter<>();
    IgniteLogger log = cctx.kernalContext().grid().log();
    // An internal future for the ability to cancel index rebuilding.
    SchemaIndexCacheFuture intRebFut = new SchemaIndexCacheFuture(cancelTok);
    SchemaIndexCacheFuture prevIntRebFut = idxRebuildFuts.put(cctx.cacheId(), intRebFut);
    // Check that the previous rebuild is completed.
    assert prevIntRebFut == null;
    cctx.kernalContext().query().onStartRebuildIndexes(cctx);
    rebuildCacheIdxFut.listen(fut -> {
        Throwable err = fut.error();
        if (err == null) {
            try {
                cctx.kernalContext().query().markAsRebuildNeeded(cctx, false);
            } catch (Throwable t) {
                err = t;
            }
        }
        if (err != null)
            U.error(log, "Failed to rebuild indexes for cache: " + cacheName, err);
        else
            cctx.kernalContext().query().onFinishRebuildIndexes(cctx);
        idxRebuildFuts.remove(cctx.cacheId(), intRebFut);
        intRebFut.onDone(err);
        outRebuildCacheIdxFut.onDone(err);
    });
    startRebuild(cctx, rebuildCacheIdxFut, clo, intRebFut.cancelToken());
    return outRebuildCacheIdxFut;
}
Also used : IgnitePageStoreManager(org.apache.ignite.internal.pagemem.store.IgnitePageStoreManager) InlineIndex(org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndex) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) SchemaIndexCacheFuture(org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheFuture) SchemaIndexCacheVisitorClosure(org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitorClosure) IgniteLogger(org.apache.ignite.IgniteLogger) Nullable(org.jetbrains.annotations.Nullable)

Example 74 with GridFutureAdapter

use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.

the class WalStateManager method init.

/**
 * Initiate WAL mode change operation.
 *
 * @param cacheNames Cache names.
 * @param enabled Enabled flag.
 * @return Future completed when operation finished.
 */
private IgniteInternalFuture<Boolean> init(Collection<String> cacheNames, boolean enabled) {
    if (!enabled && prohibitDisabling)
        return errorFuture("WAL disabling is prohibited.");
    if (F.isEmpty(cacheNames))
        return errorFuture("Cache names cannot be empty.");
    synchronized (mux) {
        if (disconnected)
            return errorFuture("Failed to initiate WAL mode change because client node is disconnected.");
        // Prepare cache and group infos.
        Map<String, IgniteUuid> caches = new HashMap<>(cacheNames.size());
        CacheGroupDescriptor grpDesc = null;
        for (String cacheName : cacheNames) {
            DynamicCacheDescriptor cacheDesc = cacheProcessor().cacheDescriptor(cacheName);
            if (cacheDesc == null)
                return errorFuture("Cache doesn't exist: " + cacheName);
            caches.put(cacheName, cacheDesc.deploymentId());
            CacheGroupDescriptor curGrpDesc = cacheDesc.groupDescriptor();
            if (grpDesc == null)
                grpDesc = curGrpDesc;
            else if (!F.eq(grpDesc.deploymentId(), curGrpDesc.deploymentId())) {
                return errorFuture("Cannot change WAL mode for caches from different cache groups [" + "cache1=" + cacheNames.iterator().next() + ", grp1=" + grpDesc.groupName() + ", cache2=" + cacheName + ", grp2=" + curGrpDesc.groupName() + ']');
            }
        }
        assert grpDesc != null;
        HashSet<String> grpCaches = new HashSet<>(grpDesc.caches().keySet());
        grpCaches.removeAll(cacheNames);
        if (!grpCaches.isEmpty()) {
            return errorFuture("Cannot change WAL mode because not all cache names belonging to the group are " + "provided [group=" + grpDesc.groupName() + ", missingCaches=" + grpCaches + ']');
        }
        if (grpDesc.config().getCacheMode() == CacheMode.LOCAL)
            return errorFuture("WAL mode cannot be changed for LOCAL cache(s): " + cacheNames);
        // WAL mode change makes sense only for persistent groups.
        if (!grpDesc.persistenceEnabled())
            return errorFuture("Cannot change WAL mode because persistence is not enabled for cache(s) [" + "caches=" + cacheNames + ", dataRegion=" + grpDesc.config().getDataRegionName() + ']');
        // Send request.
        final UUID opId = UUID.randomUUID();
        GridFutureAdapter<Boolean> fut = new GridFutureAdapter<>();
        fut.listen(new IgniteInClosure<IgniteInternalFuture<Boolean>>() {

            @Override
            public void apply(IgniteInternalFuture<Boolean> fut) {
                synchronized (mux) {
                    userFuts.remove(opId);
                }
            }
        });
        WalStateProposeMessage msg = new WalStateProposeMessage(opId, grpDesc.groupId(), grpDesc.deploymentId(), cctx.localNodeId(), caches, enabled);
        userFuts.put(opId, fut);
        try {
            cctx.discovery().sendCustomEvent(msg);
            if (log.isDebugEnabled())
                log.debug("Initiated WAL state change operation: " + msg);
        } catch (Exception e) {
            IgniteCheckedException e0 = new IgniteCheckedException("Failed to initiate WAL mode change due to unexpected exception.", e);
            fut.onDone(e0);
        }
        return fut;
    }
}
Also used : HashMap(java.util.HashMap) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteUuid(org.apache.ignite.lang.IgniteUuid) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) UUID(java.util.UUID) HashSet(java.util.HashSet) GridBoundedConcurrentLinkedHashSet(org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashSet)

Example 75 with GridFutureAdapter

use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.

the class IgniteSnapshotManager method checkSnapshot.

/**
 * The check snapshot procedure performs compute operation over the whole cluster to verify the snapshot
 * entirety and partitions consistency. The result future will be completed with an exception if this
 * exception is not related to the check procedure, and will be completed normally with the {@code IdleVerifyResult}.
 *
 * @param name Snapshot name.
 * @param grps Collection of cache group names to check.
 * @param includeCustomHandlers {@code True} to invoke all user-defined {@link SnapshotHandlerType#RESTORE}
 *                              handlers, otherwise only system consistency check will be performed.
 * @return Future with the result of execution snapshot partitions verify task, which besides calculating partition
 *         hashes of {@link IdleVerifyResultV2} also contains the snapshot metadata distribution across the cluster.
 */
public IgniteInternalFuture<SnapshotPartitionsVerifyTaskResult> checkSnapshot(String name, @Nullable Collection<String> grps, boolean includeCustomHandlers) {
    A.notNullOrEmpty(name, "Snapshot name cannot be null or empty.");
    A.ensure(U.alphanumericUnderscore(name), "Snapshot name must satisfy the following name pattern: a-zA-Z0-9_");
    A.ensure(grps == null || grps.stream().filter(Objects::isNull).collect(Collectors.toSet()).isEmpty(), "Collection of cache groups names cannot contain null elements.");
    GridFutureAdapter<SnapshotPartitionsVerifyTaskResult> res = new GridFutureAdapter<>();
    GridKernalContext kctx0 = cctx.kernalContext();
    Collection<ClusterNode> bltNodes = F.view(cctx.discovery().serverNodes(AffinityTopologyVersion.NONE), (node) -> CU.baselineNode(node, kctx0.state().clusterState()));
    kctx0.task().setThreadContext(TC_SKIP_AUTH, true);
    kctx0.task().setThreadContext(TC_SUBGRID, bltNodes);
    kctx0.task().execute(SnapshotMetadataCollectorTask.class, name).listen(f0 -> {
        if (f0.error() == null) {
            Map<ClusterNode, List<SnapshotMetadata>> metas = f0.result();
            Map<Integer, String> grpIds = grps == null ? Collections.emptyMap() : grps.stream().collect(Collectors.toMap(CU::cacheId, v -> v));
            for (List<SnapshotMetadata> nodeMetas : metas.values()) {
                for (SnapshotMetadata meta : nodeMetas) grpIds.keySet().removeAll(meta.partitions().keySet());
            }
            if (!grpIds.isEmpty()) {
                res.onDone(new SnapshotPartitionsVerifyTaskResult(metas, new IdleVerifyResultV2(Collections.singletonMap(cctx.localNode(), new IllegalArgumentException("Cache group(s) was not " + "found in the snapshot [groups=" + grpIds.values() + ", snapshot=" + name + ']')))));
                return;
            }
            kctx0.task().setThreadContext(TC_SKIP_AUTH, true);
            kctx0.task().setThreadContext(TC_SUBGRID, new ArrayList<>(metas.keySet()));
            Class<? extends AbstractSnapshotVerificationTask> cls = includeCustomHandlers ? SnapshotHandlerRestoreTask.class : SnapshotPartitionsVerifyTask.class;
            kctx0.task().execute(cls, new SnapshotPartitionsVerifyTaskArg(grps, metas)).listen(f1 -> {
                if (f1.error() == null)
                    res.onDone(f1.result());
                else if (f1.error() instanceof IgniteSnapshotVerifyException)
                    res.onDone(new SnapshotPartitionsVerifyTaskResult(metas, new IdleVerifyResultV2(((IgniteSnapshotVerifyException) f1.error()).exceptions())));
                else
                    res.onDone(f1.error());
            });
        } else {
            if (f0.error() instanceof IgniteSnapshotVerifyException)
                res.onDone(new SnapshotPartitionsVerifyTaskResult(null, new IdleVerifyResultV2(((IgniteSnapshotVerifyException) f0.error()).exceptions())));
            else
                res.onDone(f0.error());
        }
    });
    return res;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) StandaloneGridKernalContext(org.apache.ignite.internal.processors.cache.persistence.wal.reader.StandaloneGridKernalContext) GridKernalContext(org.apache.ignite.internal.GridKernalContext) PageIdUtils.toDetailString(org.apache.ignite.internal.pagemem.PageIdUtils.toDetailString) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CU(org.apache.ignite.internal.util.typedef.internal.CU) Objects(java.util.Objects) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) LinkedList(java.util.LinkedList) ArrayList(java.util.ArrayList) List(java.util.List) IdleVerifyResultV2(org.apache.ignite.internal.processors.cache.verify.IdleVerifyResultV2)

Aggregations

GridFutureAdapter (org.apache.ignite.internal.util.future.GridFutureAdapter)110 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)59 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)34 IgniteException (org.apache.ignite.IgniteException)23 ArrayList (java.util.ArrayList)21 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)21 List (java.util.List)20 UUID (java.util.UUID)20 ClusterNode (org.apache.ignite.cluster.ClusterNode)20 IgniteEx (org.apache.ignite.internal.IgniteEx)20 HashMap (java.util.HashMap)19 Map (java.util.Map)19 IgniteInterruptedCheckedException (org.apache.ignite.internal.IgniteInterruptedCheckedException)18 Test (org.junit.Test)18 Nullable (org.jetbrains.annotations.Nullable)17 Ignite (org.apache.ignite.Ignite)15 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)15 HashSet (java.util.HashSet)14 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)14 T2 (org.apache.ignite.internal.util.typedef.T2)13