/// <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;
            }
        }
Beispiel #2
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);
            }
        }