Few more tweaks to the workflow engine

This commit is contained in:
Colin Dawson 2026-02-03 11:00:09 +00:00
parent e062d15101
commit b9876b1d7b
8 changed files with 86 additions and 87 deletions

View File

@ -6,12 +6,13 @@ namespace e_suite.Workflow.Core.Extensions;
public static class StageExtensions
{
public static bool CanComplete<T>(this IStage<T> stage)
where T : TaskTypeAttribute
{
return stage.Tasks.All(x =>
x.IsCompleted());
}
//Todo can only be on a run-time instance
//public static bool CanComplete<T>(this IStage<T> stage)
// where T : TaskTypeAttribute
//{
// return stage.Tasks.All(x =>
// x.IsCompleted());
//}
private static readonly ConcurrentDictionary<Type, IEnumerable<Type>> AllowedTasksCache = new();

View File

@ -101,21 +101,22 @@ public static class TaskExtensions
}
public static bool IsCompleted(this ITask task)
{
return task.TaskState.In(TaskState.Completed, TaskState.Cancelled);
}
//Todo can only be on a run-time instance
//public static bool IsCompleted(this ITask task)
//{
// return task.TaskState.In(TaskState.Completed, TaskState.Cancelled);
//}
public static bool ReadyToActivate(this ITask task)
{
foreach (var predecessor in task.Predecessors)
{
if (!predecessor.IsCompleted())
{
return false;
}
}
//public static bool ReadyToActivate(this ITask task)
//{
// foreach (var predecessor in task.Predecessors)
// {
// if (!predecessor.IsCompleted())
// {
// return false;
// }
// }
return true;
}
// return true;
//}
}

View File

@ -14,13 +14,6 @@ public interface ITask
/// </summary>
ITask Parent { get; }
//Todo move this out to runtime only.
/// <summary>
/// Current state of the Task.
/// </summary>
TaskState TaskState { get; set; }
/// <summary>
/// Name of the task as seen by users, must be unique in the workflow.
/// </summary>
@ -68,20 +61,21 @@ public interface ITask
public IList<string> Tags { get; set; }
/// <summary>
/// Called when the task status has been progressed from Pending to Active.
///
/// Note: You can use this method to set the TaskStatus to ReadyToComplete if there is no manual processing needed for this task.
/// After this method is completed, the TaskStatus must be either Active or ReadyToComplete.
/// </summary>
/// <returns></returns>
Task OnActivateAsync();
//Todo can only be on a run-time instance
///// <summary>
///// Called when the task status has been progressed from Pending to Active.
/////
///// Note: You can use this method to set the TaskStatus to ReadyToComplete if there is no manual processing needed for this task.
///// After this method is completed, the TaskStatus must be either Active or ReadyToComplete.
///// </summary>
///// <returns></returns>
//Task OnActivateAsync();
/// <summary>
/// Called when the task status has been progressed from ReadyToComplete to Completed
/// </summary>
/// <returns>True when the task completes successfully, false when it is considered failed.</returns>
Task<bool> OnCompleteAsync();
///// <summary>
///// Called when the task status has been progressed from ReadyToComplete to Completed
///// </summary>
///// <returns>True when the task completes successfully, false when it is considered failed.</returns>
//Task<bool> OnCompleteAsync();
//Todo add support for events (soap, rest, sftp, e-mail)
}

View File

@ -25,25 +25,25 @@ public interface IWorkflow : IStage<GeneralTaskAttribute>
/// </summary>
string Description { get; set; }
//todo Move this out to runtime only.
/// <summary>
/// If the workflow has been paused, will be true.
/// </summary>
bool Paused { get; }
//Todo can only be on a run-time instance
///// <summary>
///// If the workflow has been paused, will be true.
///// </summary>
//bool Paused { get; }
///// <summary>
///// Called when the task status has been progressed from Pending to Active.
/////
///// Note: You can use this method to set the TaskStatus to ReadyToComplete if there is no manual processing needed for this task.
///// After this method is completed, the TaskStatus must be either Active or ReadyToComplete.
///// </summary>
///// <returns></returns>
//Task OnActivateAsync();
/// <summary>
/// Called when the task status has been progressed from Pending to Active.
///
/// Note: You can use this method to set the TaskStatus to ReadyToComplete if there is no manual processing needed for this task.
/// After this method is completed, the TaskStatus must be either Active or ReadyToComplete.
/// </summary>
/// <returns></returns>
Task OnActivateAsync();
/// <summary>
/// Called when the task status has been progressed from ReadyToComplete to Completed
/// When this method is completed the state must be either Active, or Completed.
/// </summary>
/// <returns></returns>
Task OnCompleteAsync();
///// <summary>
///// Called when the task status has been progressed from ReadyToComplete to Completed
///// When this method is completed the state must be either Active, or Completed.
///// </summary>
///// <returns></returns>
//Task OnCompleteAsync();
}

View File

@ -7,7 +7,6 @@ public abstract class TaskBase : ITask
{
public Guid Guid { get; set; } = Guid.CreateVersion7();
public required ITask Parent { get; set; }
public TaskState TaskState { get; set; } = TaskState.Pending;
public required string Name { get; set; }
public string Description { get; set; } = string.Empty;
public IList<ITask> Predecessors { get; set; } = new List<ITask>();
@ -19,13 +18,14 @@ public abstract class TaskBase : ITask
public required TimeSpan Duration { get; set; }
public IList<string> Tags { get; set; } = new List<string>();
public virtual Task OnActivateAsync()
{
return Task.CompletedTask;
}
//Todo can only be on a run-time instance
//public virtual Task OnActivateAsync()
//{
// return Task.CompletedTask;
//}
public virtual Task<bool> OnCompleteAsync()
{
return Task.FromResult(true);
}
//public virtual Task<bool> OnCompleteAsync()
//{
// return Task.FromResult(true);
//}
}

View File

@ -10,9 +10,10 @@ public class ApprovalTask : TaskBase, IStage<ApprovalTaskAttribute>, IFailedLoop
public ICollection<ITask> Tasks { get; } = new List<ITask>();
public override Task<bool> OnCompleteAsync()
{
//Todo can only be on a run-time instance
//public override Task<bool> OnCompleteAsync()
//{
return Task.FromResult(true);
}
// return Task.FromResult(true);
//}
}

View File

@ -1,5 +1,4 @@
using e_suite.Workflow.Core.Attributes;
using e_suite.Workflow.Core.Enums;
namespace e_suite.Workflow.Core.Tasks;
@ -9,9 +8,10 @@ namespace e_suite.Workflow.Core.Tasks;
[GeneralTask]
public class MilestoneTask : TaskBase
{
public override async Task OnActivateAsync()
{
await base.OnActivateAsync();
TaskState = TaskState.ReadyToComplete;
}
//Todo can only be on a run-time instance
//public override async Task OnActivateAsync()
//{
// await base.OnActivateAsync();
// TaskState = TaskState.ReadyToComplete;
//}
}

View File

@ -21,12 +21,14 @@ public class WorkflowVersion : IWorkflow
public WorkflowState CurrentState { get; set; } = WorkflowState.Pending;
public required string ActivityNameTemplate { get; set; }
public string Description { get; set; } = string.Empty;
public bool Paused { get; } = false;
public async Task OnActivateAsync()
{
}
public async Task OnCompleteAsync()
{
}
//Todo can only be on a run-time instance
//public bool Paused { get; } = false;
//public async Task OnActivateAsync()
//{
//}
//public async Task OnCompleteAsync()
//{
//}
}