using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using RudderSdk.Core.Models; namespace RudderSdk.Core; public sealed partial class ScenarioService { private void Persist() { var store = _client.Options.PlanStateStore; if (store == null) return; if (_runs.Count == 0) { store.State = null; return; } var state = new PersistedScenarioState { Runs = _runs.Values.Select(run => run.ToPersisted()).ToList() }; store.State = JsonConvert.SerializeObject(state); } private sealed class RuntimeRun { public RuntimeRun(string runId, ExecutionPlan plan) { RunId = runId; Plan = plan; } public string RunId { get; } public ExecutionPlan Plan { get; } public Dictionary ActiveNodes { get; } = new(); public HashSet CompletedHandles { get; } = new(StringComparer.Ordinal); public PersistedRun ToPersisted() { return new PersistedRun { RunId = RunId, Plan = Plan, ActiveNodes = ActiveNodes.Values.ToList(), CompletedHandles = CompletedHandles.ToList() }; } public static RuntimeRun FromPersisted(PersistedRun saved) { var run = new RuntimeRun(saved.RunId, saved.Plan); if (saved.ActiveNodes != null) { foreach (var node in saved.ActiveNodes) { if (!string.IsNullOrEmpty(node?.NodeId)) run.ActiveNodes[node.NodeId] = node; } } if (saved.CompletedHandles != null) { foreach (var handle in saved.CompletedHandles) run.CompletedHandles.Add(handle); } return run; } } private sealed class PersistedScenarioState { public List? Runs { get; set; } } private sealed class PersistedRun { public string RunId { get; set; } = string.Empty; public ExecutionPlan Plan { get; set; } = null!; public List? ActiveNodes { get; set; } public List? CompletedHandles { get; set; } } private sealed class ActiveNodeState { public string NodeId { get; set; } = string.Empty; public DateTimeOffset? WaitDeadlineUtc { get; set; } } }