namespace s8n_runtime; using System.Text.Json; using System.Text.Json.Serialization; public class WorkflowRuntimeRunner { private static readonly JsonSerializerOptions serializerOptions = new(JsonSerializerDefaults.Web) { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; public static async Task Main(string[] args, bool silent = false) where TWorkflow : WorkflowRuntime { if (!silent) Console.WriteLine("Starting workflow..."); var cts = new CancellationTokenSource(); Console.CancelKeyPress += (s, e) => { if (!silent) Console.WriteLine("Canceling..."); cts.Cancel(); e.Cancel = true; }; async Task FindWorkflowJsonFile() { if (args.FirstOrDefault(a => a.EndsWith("workflow.json")) is string jsonArg) return jsonArg; if (Environment.GetEnvironmentVariable("WORKFLOW_FILE") is string workflowFile) return workflowFile; var testPath = Path.GetFullPath("workflow.json"); if (File.Exists(testPath)) { return testPath; } return null; } var filePath = await FindWorkflowJsonFile(); TWorkflow runtime; if (filePath == null) { runtime = Activator.CreateInstance(); } else { runtime = JsonSerializer.Deserialize(File.OpenRead(filePath), serializerOptions)!; } runtime.Prepare(); try { await runtime.RunAsync(cts.Token); } catch (TaskCanceledException) { if (!silent) Console.WriteLine("Canceled."); } finally { await runtime.OnStop(); } if (runtime.StoreState == RuntimeStateStoreStrategy.WhenExit) { if (string.IsNullOrEmpty(filePath) is false) { JsonSerializer.Serialize(File.OpenWrite(filePath), runtime, serializerOptions); } } if (!silent) Console.WriteLine("Workflow stopped."); return 0; } }