93 lines
2.7 KiB
C#
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()}";
|
|||
|
|
}
|
|||
|
|
}
|