Files
Sharp8N-Runtime/s8n-runtime/WorkflowRuntime.cs
2025-12-24 21:26:35 +03:00

93 lines
2.7 KiB
C#

namespace s8n_runtime;
public abstract class WorkflowRuntime
{
private RuntimeStatus status;
public RuntimeStateStoreStrategy StoreState { get; set; } = RuntimeStateStoreStrategy.WhenExit;
protected IServiceProvider? serviceProvider;
public DateTime Timestamp => DateTime.Now;
public RuntimeStatus Status
{
get => status;
set
{
status = value;
WorkflowEditApiChannel.LogServerChannel?.Writer.TryWrite(new(string.Empty, "Workflow.Status", value));
}
}
public Dictionary<string, object> Settings { get; private set; } = [];
public IEnumerable<IWorkflowRuntimeNode> AllNodes()
{
foreach (var f in EnumFields())
{
var value = f.GetValue(this);
if (value is IWorkflowRuntimeNode node)
yield return node;
}
}
private IEnumerable<System.Reflection.FieldInfo> EnumFields()
{
return GetType()
.GetFields(System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.NonPublic)
.Where(f => f.DeclaringType == GetType());
}
public virtual void Prepare()
{
foreach (var f in EnumFields())
{
var value = f.GetValue(this);
if (value is null)
{
f.SetValue(this, serviceProvider?.GetService(f.FieldType) ??
Activator.CreateInstance(f.FieldType));
}
}
}
public async virtual Task RunAsync(CancellationToken cancellation)
{
foreach (var node in AllNodes())
{
cancellation.ThrowIfCancellationRequested();
if (node is IWorkflowNodeRunnable runnable)
await runnable.OnStart(this, cancellation);
if (node.Status == RuntimeStatus.NotReady)
{
node.Status = RuntimeStatus.Started;
}
}
Status = RuntimeStatus.Started;
}
public virtual async Task OnStop()
{
foreach (var node in AllNodes())
{
// When already stopped or skipped on start
if (node.Status == RuntimeStatus.Skipped ||
node.Status == RuntimeStatus.Stopped) continue;
if (node is IWorkflowNodeRunnable runnable)
await runnable.OnStop();
}
foreach (var node in AllNodes().OfType<IDisposable>())
{
node.Dispose();
}
Status = RuntimeStatus.Stopped;
}
public override string ToString()
{
return $"Status: {Status}, Count: {AllNodes().Count()}";
}
}