How to stop a Timer activity after a certain condition is reached in Elsa Workflow

124 views Asked by At

I'm very new to Elsa workflow, please forgive my mistakes.

I have customized the document approval workflow provided in the documentation for my need. Everything is working fine.

I have a use case now for that I need to send reminders only 3 times and that too on a different time intervals. Eg. I need to send reminder email for 3 times only 1st time : after 1 hour of sending the approval email 2nd time : after 5 hour 3rd time : after 24 hour

after that again wait for 24 hour, if no response came, Cancel the workflow/make workflow as faulted. No reminders should be sent more than 3 and Workflow should be ended as faulted or cancelled. How to achieve this please help me. I'm very new to this.

Here, GetTimerValue() and CheckReminderLimitReached() are custom methods I have created for my use.

Approach I have used (Not a good approch, But I need like this only): When Approval email is sent, I'm maintaining a counter file in my local storage to track the no of reminders sent (I don't want to store it in DB). GetTimerValue() will check the counter value and based on the 'n'th reminder it is, it will return the expected Duration value for that reminder and increase the counter by 1.

CheckReminderLimitReached() returns a boolean that counter value reached the limit or not.

How can I use this logic to achieve this use case. Please help, I'm stuck here from 5 days.

Project info:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Elsa" Version="2.13.0" />
    <PackageReference Include="Elsa.Activities.Email" Version="2.13.0" />
    <PackageReference Include="Elsa.Activities.Http" Version="2.13.0" />
    <PackageReference Include="Elsa.Activities.Temporal.Quartz" Version="2.13.0" />
    <PackageReference Include="Elsa.Designer.Components.Web" Version="2.13.0" />
    <PackageReference Include="Elsa.Persistence.EntityFramework.Sqlite" Version="2.13.0" />
    <PackageReference Include="Elsa.Scripting.JavaScript" Version="2.13.0" />
    <PackageReference Include="Elsa.Scripting.Liquid" Version="2.13.0" />
    <PackageReference Include="Elsa.Server.Api" Version="2.13.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="7.0.0" />
  </ItemGroup>

  <ItemGroup>
    <Folder Include="Utility\" />
  </ItemGroup>

  <ItemGroup>
    <Content Update="log4net.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

</Project>

Bellow is the code I tried

fork
  .When("Remind")
  //.Timer(Duration.FromSeconds(0)).WithName("Reminder")
  //.IfTrue(CheckReminderLimitReached,context=>context.ThenNamed("Reminder").WorkflowBuilder.Finish())
  //.IfFalse(CheckReminderLimitReached)

  //.If(context => CheckReminderLimitReached(context))
  //    .When("true")
  //        .CancelTimer(context => context.ActivityId).Break()
  
  .Timer(context => GetTimerValue(context)).WithName("Reminder")
  .If(context=> CheckReminderLimitReached(context)).When("true").Timer().CancelTimer(context => context.ActivityId).Finish()
  .SendEmail( // some code
)

Below is the custom method code. I'm tweaking it for testing, but you will get Idea what I'm trying to do here

 private bool CheckReminderLimitReached(ActivityExecutionContext context)
        {
            string ticketId = context.GetVariable<ApprovalRequestModel>("Approval")!.ticket_id!;
            string path = $"C:\\Apps\\DotNet\\UatTickets\\{ticketId}\\rem_counter.txt";

            var content = string.Empty;
            var reminders = 0;
            if (File.Exists(path))
            {
               content = File.ReadAllText(path);
            }

            if (!string.IsNullOrEmpty(content))
            {
               reminders = Int32.Parse(content);
            }

            bool result = reminders == 3;
            return result;
            
        }

        private Duration GetTimerValue(ActivityExecutionContext context)
        {
            
            string ticketId = context.GetVariable<ApprovalRequestModel>("Approval")!.ticket_id!;
            string path = $"C:\\Apps\\DotNet\\UatTickets\\{ticketId}\\rem_counter.txt";

            var timerDict = new Dictionary<int, int>()
            {
                {0,60 },
                {1,120 },
                {2,180 },
                {3,180 }
            };

            var reminderCount = 0;

            var content = File.ReadAllText(path);
            if (!string.IsNullOrEmpty(content))
            {
                reminderCount = Int32.Parse(content);
            }

            // increase the counter
            File.WriteAllText(path, $"{reminderCount+1}");

            //return Duration.FromSeconds(10);
            var result = Duration.FromSeconds(timerDict[reminderCount]);
            return result;

        }
0

There are 0 answers