using System.Collections.Concurrent; using MAF1.Decisions; using MAF1.Plugins; namespace MAF1.Web; internal sealed class WorkflowSession { public required string RunId { get; init; } public required WorkflowGraph Graph { get; init; } public required NodeCatalogSnapshot Catalog { get; init; } public required List Order { get; init; } public required Dictionary> Outputs { get; init; } public required List Steps { get; init; } public int NextIndex { get; set; } public DecisionRequest? Pending { get; set; } public bool Completed { get; set; } public WorkflowRunResult LastResult { get; set; } = new(); public DecisionAnswer? AppliedDecision { get; set; } public CancellationTokenSource TimeoutCts { get; set; } = new(); public SemaphoreSlim Mutex { get; } = new(1, 1); public object Sync { get; } = new(); } public sealed class WorkflowRunStore { private readonly ConcurrentDictionary _sessions = new(StringComparer.OrdinalIgnoreCase); internal bool TryAdd(WorkflowSession session) => _sessions.TryAdd(session.RunId, session); internal bool TryGet(string runId, out WorkflowSession? session) => _sessions.TryGetValue(runId, out session); public WorkflowRunResult? GetResult(string runId) => _sessions.TryGetValue(runId, out WorkflowSession? session) ? session.LastResult : null; }