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