/// <summary> /// Wait for ongoing checkpoint to complete /// </summary> /// <returns></returns> public async ValueTask CompleteCheckpointAsync(CancellationToken token = default) { if (LightEpoch.AnyInstanceProtected()) { throw new FasterException("Cannot use CompleteCheckpointAsync when using legacy or non-async sessions"); } token.ThrowIfCancellationRequested(); while (true) { var systemState = this.systemState; if (systemState.phase == Phase.REST || systemState.phase == Phase.PREPARE_GROW || systemState.phase == Phase.IN_PROGRESS_GROW) { return; } List <ValueTask> valueTasks = new List <ValueTask>(); ThreadStateMachineStep <Empty, Empty, Empty, NullFasterSession>(null, NullFasterSession.Instance, valueTasks, token); if (valueTasks.Count == 0) { continue; // we need to re-check loop, so we return only when we are at REST } foreach (var task in valueTasks) { if (!task.IsCompleted) { await task; } } } }
/// <summary> /// Wait for ongoing checkpoint to complete /// </summary> /// <returns></returns> public async ValueTask CompleteCheckpointAsync(CancellationToken token = default) { if (LightEpoch.AnyInstanceProtected()) { throw new FasterException("Cannot use CompleteCheckpointAsync when using legacy or non-async sessions"); } token.ThrowIfCancellationRequested(); while (true) { var systemState = _systemState; if (systemState.phase == Phase.REST || systemState.phase == Phase.PREPARE_GROW || systemState.phase == Phase.IN_PROGRESS_GROW) { return; } await HandleCheckpointingPhasesAsync(null, null); } }
/// <summary> /// Grow the hash index by a factor of two. Make sure to take a full checkpoint /// after growth, for persistence. /// </summary> /// <returns>Whether the grow completed</returns> public bool GrowIndex() { if (LightEpoch.AnyInstanceProtected()) { throw new FasterException("Cannot use GrowIndex when using legacy or non-async sessions"); } if (!StartStateMachine(new IndexResizeStateMachine())) { return(false); } epoch.Resume(); try { while (true) { SystemState _systemState = SystemState.Copy(ref systemState); if (_systemState.Phase == Phase.IN_PROGRESS_GROW) { SplitBuckets(0); epoch.ProtectAndDrain(); } else { SystemState.RemoveIntermediate(ref _systemState); if (_systemState.Phase != Phase.PREPARE_GROW && _systemState.Phase != Phase.IN_PROGRESS_GROW) { return(true); } } } } finally { epoch.Suspend(); } }
/// <summary> /// Wait for ongoing checkpoint to complete /// </summary> /// <returns></returns> public async ValueTask CompleteCheckpointAsync(CancellationToken token = default) { if (LightEpoch.AnyInstanceProtected()) { throw new FasterException("Cannot use CompleteCheckpointAsync when using legacy or non-async sessions"); } token.ThrowIfCancellationRequested(); while (true) { var systemState = this.systemState; if (systemState.phase == Phase.REST || systemState.phase == Phase.PREPARE_GROW || systemState.phase == Phase.IN_PROGRESS_GROW) { return; } // TODO: Do we need access to functions here? // If yes then move this to either faster legacy or client session. await ThreadStateMachineStep <Empty, Empty, Empty, NullFasterSession>(null, NullFasterSession.Instance, true, token); } }