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