/// <inheritdoc />
        public void OnThreadState <Key, Value, Input, Output, Context, FasterSession>(
            SystemState current, SystemState prev,
            FasterKV <Key, Value> faster,
            FasterKV <Key, Value> .FasterExecutionContext <Input, Output, Context> ctx,
            FasterSession fasterSession,
            List <ValueTask> valueTasks,
            CancellationToken token = default)
            where FasterSession : IFasterSession
        {
            switch (current.Phase)
            {
            case Phase.PREPARE:
                if (ctx != null)
                {
                    if (!ctx.markers[EpochPhaseIdx.Prepare])
                    {
                        ctx.markers[EpochPhaseIdx.Prepare] = true;
                    }
                }

                faster.epoch.Mark(EpochPhaseIdx.Prepare, current.Version);
                if (faster.epoch.CheckIsComplete(EpochPhaseIdx.Prepare, current.Version))
                {
                    faster.GlobalStateMachineStep(current);
                }
                break;

            case Phase.IN_PROGRESS:
                if (ctx != null)
                {
                    // Need to be very careful here as threadCtx is changing
                    var _ctx   = prev.Phase == Phase.IN_PROGRESS ? ctx.prevCtx : ctx;
                    var tokens = faster._hybridLogCheckpoint.info.checkpointTokens;
                    if (!faster.SameCycle(ctx, current) || tokens == null)
                    {
                        return;
                    }

                    if (!_ctx.markers[EpochPhaseIdx.InProgress])
                    {
                        faster.AtomicSwitch(ctx, ctx.prevCtx, _ctx.version, tokens);
                        faster.InitContext(ctx, ctx.prevCtx.sessionID, ctx.prevCtx.sessionName, ctx.prevCtx.serialNum);

                        // Has to be prevCtx, not ctx
                        ctx.prevCtx.markers[EpochPhaseIdx.InProgress] = true;
                    }
                }

                faster.epoch.Mark(EpochPhaseIdx.InProgress, current.Version);
                if (faster.epoch.CheckIsComplete(EpochPhaseIdx.InProgress, current.Version))
                {
                    faster.GlobalStateMachineStep(current);
                }
                break;

            case Phase.REST:
                break;
            }
        }
        /// <inheritdoc />
        public async ValueTask OnThreadState <Key, Value, Input, Output, Context, FasterSession>(
            SystemState current,
            SystemState prev,
            FasterKV <Key, Value> faster,
            FasterKV <Key, Value> .FasterExecutionContext <Input, Output, Context> ctx,
            FasterSession fasterSession,
            bool async = true,
            CancellationToken token = default)
            where Key : new()
            where Value : new()
            where FasterSession : IFasterSession
        {
            switch (current.phase)
            {
            case Phase.PREP_INDEX_CHECKPOINT:
                if (ctx != null)
                {
                    if (!ctx.markers[EpochPhaseIdx.PrepareForIndexCheckpt])
                    {
                        ctx.markers[EpochPhaseIdx.PrepareForIndexCheckpt] = true;
                    }
                    faster.epoch.Mark(EpochPhaseIdx.PrepareForIndexCheckpt, current.version);
                }

                if (faster.epoch.CheckIsComplete(EpochPhaseIdx.PrepareForIndexCheckpt, current.version))
                {
                    faster.GlobalStateMachineStep(current);
                }
                break;

            case Phase.INDEX_CHECKPOINT:
                if (ctx != null)
                {
                    // Resetting the marker for a potential FULL or INDEX_ONLY checkpoint in the future
                    ctx.markers[EpochPhaseIdx.PrepareForIndexCheckpt] = false;
                }

                if (async && !faster.IsIndexFuzzyCheckpointCompleted())
                {
                    fasterSession?.UnsafeSuspendThread();
                    await faster.IsIndexFuzzyCheckpointCompletedAsync(token);

                    fasterSession?.UnsafeResumeThread();
                }

                faster.GlobalStateMachineStep(current);
                break;
            }
        }
        /// <inheritdoc />
        public virtual void OnThreadState <Key, Value, Input, Output, Context, FasterSession>(
            SystemState current,
            SystemState prev, FasterKV <Key, Value> faster,
            FasterKV <Key, Value> .FasterExecutionContext <Input, Output, Context> ctx,
            FasterSession fasterSession,
            List <ValueTask> valueTasks,
            CancellationToken token = default)
            where FasterSession : IFasterSession
        {
            if (current.Phase != Phase.PERSISTENCE_CALLBACK)
            {
                return;
            }

            if (ctx != null)
            {
                if (!ctx.prevCtx.markers[EpochPhaseIdx.CheckpointCompletionCallback])
                {
                    faster.IssueCompletionCallback(ctx, fasterSession);
                    ctx.prevCtx.markers[EpochPhaseIdx.CheckpointCompletionCallback] = true;
                }
            }

            faster.epoch.Mark(EpochPhaseIdx.CheckpointCompletionCallback, current.Version);
            if (faster.epoch.CheckIsComplete(EpochPhaseIdx.CheckpointCompletionCallback, current.Version))
            {
                faster.GlobalStateMachineStep(current);
            }
        }
        /// <inheritdoc />
        public async ValueTask OnThreadState <Key, Value, Input, Output, Context, FasterSession>(
            SystemState current,
            SystemState prev,
            FasterKV <Key, Value> faster,
            FasterKV <Key, Value> .FasterExecutionContext <Input, Output, Context> ctx,
            FasterSession fasterSession,
            bool async = true,
            CancellationToken token = default) where Key : new()
            where Value : new()
            where FasterSession : IFasterSession
        {
            if (current.phase != Phase.WAIT_INDEX_CHECKPOINT)
            {
                return;
            }

            if (async && !faster.IsIndexFuzzyCheckpointCompleted())
            {
                fasterSession?.UnsafeSuspendThread();
                await faster.IsIndexFuzzyCheckpointCompletedAsync(token);

                fasterSession?.UnsafeResumeThread();
            }

            faster.GlobalStateMachineStep(current);
        }
示例#5
0
        /// <inheritdoc />
        public void OnThreadState <Key, Value, Input, Output, Context, FasterSession>(
            SystemState current,
            SystemState prev,
            FasterKV <Key, Value> faster,
            FasterKV <Key, Value> .FasterExecutionContext <Input, Output, Context> ctx,
            FasterSession fasterSession,
            List <ValueTask> valueTasks,
            CancellationToken token = default)
            where Key : new()
            where Value : new()
            where FasterSession : IFasterSession
        {
            switch (current.phase)
            {
            case Phase.PREP_INDEX_CHECKPOINT:
                faster.GlobalStateMachineStep(current);
                break;

            case Phase.WAIT_INDEX_CHECKPOINT:
                var notify = faster.IsIndexFuzzyCheckpointCompleted();
                notify = notify || !faster.SameCycle(current);

                if (valueTasks != null && !notify)
                {
                    var t = faster.IsIndexFuzzyCheckpointCompletedAsync(token);
                    if (!faster.SameCycle(current))
                    {
                        notify = true;
                    }
                    else
                    {
                        valueTasks.Add(t);
                    }
                }

                if (!notify)
                {
                    return;
                }
                faster.GlobalStateMachineStep(current);
                break;
            }
        }
        /// <inheritdoc />
        public override void OnThreadState <Key, Value, Input, Output, Context, FasterSession>(
            SystemState current,
            SystemState prev,
            FasterKV <Key, Value> faster,
            FasterKV <Key, Value> .FasterExecutionContext <Input, Output, Context> ctx,
            FasterSession fasterSession,
            List <ValueTask> valueTasks,
            CancellationToken token = default)
        {
            base.OnThreadState(current, prev, faster, ctx, fasterSession, valueTasks, token);

            if (current.phase != Phase.WAIT_FLUSH)
            {
                return;
            }

            if (ctx == null || !ctx.prevCtx.markers[EpochPhaseIdx.WaitFlush])
            {
                var s = faster._hybridLogCheckpoint.flushedSemaphore;

                var notify = faster.hlog.FlushedUntilAddress >= faster._hybridLogCheckpoint.info.finalLogicalAddress;
                notify = notify || !faster.SameCycle(current);

                if (valueTasks != null && !notify)
                {
                    Debug.Assert(s != null);
                    valueTasks.Add(new ValueTask(s.WaitAsync(token).ContinueWith(t => s.Release())));
                }

                if (!notify)
                {
                    return;
                }

                if (ctx != null)
                {
                    ctx.prevCtx.markers[EpochPhaseIdx.WaitFlush] = true;
                }
            }

            if (ctx != null)
            {
                faster.epoch.Mark(EpochPhaseIdx.WaitFlush, current.version);
            }

            if (faster.epoch.CheckIsComplete(EpochPhaseIdx.WaitFlush, current.version))
            {
                faster.GlobalStateMachineStep(current);
            }
        }
        /// <inheritdoc />
        public virtual void OnThreadState <Key, Value, Input, Output, Context, FasterSession>(
            SystemState current,
            SystemState prev, FasterKV <Key, Value> faster,
            FasterKV <Key, Value> .FasterExecutionContext <Input, Output, Context> ctx,
            FasterSession fasterSession,
            List <ValueTask> valueTasks,
            CancellationToken token = default)
            where Key : new()
            where Value : new()
            where FasterSession : IFasterSession
        {
            if (current.phase != Phase.PERSISTENCE_CALLBACK)
            {
                return;
            }

            if (ctx != null)
            {
                if (!ctx.prevCtx.markers[EpochPhaseIdx.CheckpointCompletionCallback])
                {
                    if (ctx.prevCtx.serialNum != -1)
                    {
                        var commitPoint = new CommitPoint
                        {
                            UntilSerialNo     = ctx.prevCtx.serialNum,
                            ExcludedSerialNos = ctx.prevCtx.excludedSerialNos
                        };

                        // Thread local action
                        fasterSession?.CheckpointCompletionCallback(ctx.guid, commitPoint);

                        // Set to null to indicate already called (for re-entering sessions)
                        ctx.prevCtx.excludedSerialNos = null;
                    }

                    ctx.prevCtx.markers[EpochPhaseIdx.CheckpointCompletionCallback] = true;
                }

                faster.epoch.Mark(EpochPhaseIdx.CheckpointCompletionCallback, current.version);
            }

            if (faster.epoch.CheckIsComplete(EpochPhaseIdx.CheckpointCompletionCallback, current.version))
            {
                faster.GlobalStateMachineStep(current);
            }
        }
        /// <inheritdoc />
        public void GlobalAfterEnteringState <Key, Value>(
            SystemState next,
            FasterKV <Key, Value> faster)
        {
            switch (next.phase)
            {
            case Phase.PREPARE_GROW:
                faster.epoch.BumpCurrentEpoch(() => faster.GlobalStateMachineStep(next));
                break;

            case Phase.IN_PROGRESS_GROW:
            case Phase.REST:
                // nothing to do
                break;

            default:
                throw new FasterException("Invalid Enum Argument");
            }
        }
示例#9
0
        /// <inheritdoc />
        public ValueTask OnThreadState <Key, Value, Input, Output, Context, Functions>(
            SystemState current, SystemState prev,
            FasterKV <Key, Value, Input, Output, Context, Functions> faster,
            FasterKV <Key, Value, Input, Output, Context, Functions> .FasterExecutionContext ctx,
            ClientSession <Key, Value, Input, Output, Context, Functions> clientSession,
            bool async = true,
            CancellationToken token = default)
            where Key : new()
            where Value : new()
            where Functions : IFunctions <Key, Value, Input, Output, Context>
        {
            switch (current.phase)
            {
            case Phase.PREPARE:
                if (ctx != null)
                {
                    if (!ctx.markers[EpochPhaseIdx.Prepare])
                    {
                        if (!faster.RelaxedCPR)
                        {
                            faster.AcquireSharedLatchesForAllPendingRequests(ctx);
                        }
                        ctx.markers[EpochPhaseIdx.Prepare] = true;
                    }

                    faster.epoch.Mark(EpochPhaseIdx.Prepare, current.version);
                }

                if (faster.epoch.CheckIsComplete(EpochPhaseIdx.Prepare, current.version))
                {
                    faster.GlobalStateMachineStep(current);
                }
                break;

            case Phase.IN_PROGRESS:
                if (ctx != null)
                {
                    // Need to be very careful here as threadCtx is changing
                    var _ctx = prev.phase == Phase.IN_PROGRESS ? ctx.prevCtx : ctx;

                    if (!_ctx.markers[EpochPhaseIdx.InProgress])
                    {
                        faster.AtomicSwitch(ctx, ctx.prevCtx, _ctx.version);
                        faster.InitContext(ctx, ctx.prevCtx.guid, ctx.prevCtx.serialNum);

                        // Has to be prevCtx, not ctx
                        ctx.prevCtx.markers[EpochPhaseIdx.InProgress] = true;
                    }

                    faster.epoch.Mark(EpochPhaseIdx.InProgress, current.version);
                }

                // Has to be prevCtx, not ctx
                if (faster.epoch.CheckIsComplete(EpochPhaseIdx.InProgress, current.version))
                {
                    faster.GlobalStateMachineStep(current);
                }
                break;

            case Phase.WAIT_PENDING:
                if (ctx != null)
                {
                    if (!faster.RelaxedCPR && !ctx.prevCtx.markers[EpochPhaseIdx.WaitPending])
                    {
                        if (ctx.prevCtx.HasNoPendingRequests)
                        {
                            ctx.prevCtx.markers[EpochPhaseIdx.WaitPending] = true;
                        }
                        else
                        {
                            break;
                        }
                    }

                    faster.epoch.Mark(EpochPhaseIdx.WaitPending, current.version);
                }

                if (faster.epoch.CheckIsComplete(EpochPhaseIdx.WaitPending, current.version))
                {
                    faster.GlobalStateMachineStep(current);
                }
                break;

            case Phase.REST:
                break;
            }

            return(default);