danielgerlag / workflow-core

Lightweight workflow engine for .NET Standard
MIT License
5.4k stars 1.2k forks source link

here always have 8 - 10 seconds latency to execute next step after executed delay step #1316

Open tclugao opened 1 week ago

tclugao commented 1 week ago

Describe the bug here always have 8 - 10 seconds of latency to execute the next step after the executed delay step image

To Reproduce (1) the workflow json is as following:

{
    "Id": "umms-workflow",
    "Steps": [
        {
            "Id": "StartStep",
            "StepType": "MyDemoApp.Worlkflow.UMMS.Steps.StartStep, MyDemoApp",
            "NextStepId": "NotifyStep_1"
        },
        {
            "Id": "NotifyStep_1",
            "StepType": "MyDemoApp.Worlkflow.UMMS.Steps.NotificationStep, MyDemoApp",
            "NextStepId": "WaitStep_1"
        },
        {
            "Id": "WaitStep_1",
            "StepType": "MyDemoApp.Worlkflow.UMMS.Steps.Sequence, MyDemoApp",
            "Inputs": {
                "FlagNameToReset": "data.IsWorkflowSkippedNameOf"
            },
            "Do": [
                [
                    {
                        "Id": "DelayStep_1",
                        "Inputs": {
                            "Period": "TimeSpan.FromSeconds(30)"
                        },
                        "StepType": "MyDemoApp.Worlkflow.UMMS.Steps.DelayStep, MyDemoApp",
                        "CancelCondition": "data.IsWorkflowSkipped",
                        "NextStepId": "ExtraWaitStep_1"
                    },
                    {
                        "Id": "ExtraWaitStep_1",
                        "StepType": "MyDemoApp.Worlkflow.UMMS.Steps.ExtraWaitStep, MyDemoApp",
                        "CancelCondition": "data.IsWorkflowSkipped",
                        "Outputs": {
                            "IsWorkflowSkipped": "true"
                        }
                    }
                ]
            ],
            "NextStepId": "EndStep"
        },
        {
            "Id": "EndStep",
            "Outputs": {
                "IsWorkflowCompleted": "true"
            },
            "StepType": "MyDemoApp.Worlkflow.UMMS.Steps.EndStep, MyDemoApp"
        }
    ],
    "Version": 1,
    "DataType": "MyDemoApp.Worlkflow.UMMS.UmmsWorkflowData, MyDemoApp"
}

(2) the MyDemoApp.Worlkflow.UMMS.Steps.Sequence is as following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WorkflowCore.Exceptions;
using WorkflowCore.Interface;
using WorkflowCore.Models;
using WorkflowCore.Primitives;

namespace MyDemoApp.Worlkflow.UMMS.Steps
{
    public class Sequence : ContainerStepBody
    {
        public string? FlagNameToReset { get; set; }

        public override ExecutionResult Run(IStepExecutionContext context)
        {
            if (context.PersistenceData == null)
            {
                return ExecutionResult.Branch(new List<object> { context.Item }, new ControlPersistenceData { ChildrenActive = true });
            }

            if ((context.PersistenceData is ControlPersistenceData) && ((context.PersistenceData as ControlPersistenceData).ChildrenActive))
            {
                if (context.Workflow.IsBranchComplete(context.ExecutionPointer.Id))
                {
                    ResetCancelFlag(context);
                    return ExecutionResult.Next();
                }

                return ExecutionResult.Persist(context.PersistenceData);
            }

            throw new CorruptPersistenceDataException();
        }

        private void ResetCancelFlag(IStepExecutionContext context)
        {
            var propertyInfo = context.Workflow.Data.GetType().GetProperty(FlagNameToReset);

            if (propertyInfo != null && propertyInfo.PropertyType == typeof(bool))
            {
                propertyInfo.SetValue(context.Workflow.Data, false);
            }
        }

    }
}

(3) the MyDemoApp.Worlkflow.UMMS.Steps.DelayStep is as following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WorkflowCore.Interface;
using WorkflowCore.Models;

namespace MyDemoApp.Worlkflow.UMMS.Steps
{
    public class DelayStep : StepBody
    {
        public TimeSpan Period { get; set; }

        public override ExecutionResult Run(IStepExecutionContext context)
        {
            if (context.PersistenceData != null)
            {
                return ExecutionResult.Next();
            }

            Console.WriteLine("Delay " + Period + " seconds from " + context.Workflow.Id + " at " + DateTime.Now);
            return ExecutionResult.Sleep(Period, true);

        }

    }
}

(4) Other Step Class you can just print some logs, no logic.

Expected behavior We expected after 30 seconds, the ExtraWait step will be executed in time after DelayStep finished

Additional context Add any other context about the problem here.