Azure / durabletask

Durable Task Framework allows users to write long running persistent workflows in C# using the async/await capabilities.
Apache License 2.0
1.53k stars 296 forks source link

Timer not firing #1169

Open PauloDeJesus-JT opened 1 month ago

PauloDeJesus-JT commented 1 month ago

In one of my orchestrations a timer gets based on a date specified in the orchestration input object. This date sometimes needs to be updated after the orchestration has started. I am currently trying to implement an event that cancels the existing timer and creates a new timer with the updated date.

I am able to cancel the existing timer successfully and also I am able to set a new timer but the new timer does not seem to be firing.

image

my onEvent method in my orchestration finds the required event handler based on the input and then calls the HandleProcess method.

public override async void OnEvent(OrchestrationContext context, string eventName, string input)
{
    IEventHandler eventHandler = await context.ScheduleTask<IEventHandler>(typeof(GetEventHandler), eventName);

    EventHandlerInput eventInput = new EventHandlerInput(context, customState, input);
    customState = eventHandler.HandleProcess(eventInput);
}

The date change event handler HandleProcess method cancels the current timer and schedules a new timer

public CustomOrchestrationState HandleProcess<T>(T input)
{
  EventHandlerInput customInput = (input as EventHandlerInput);

  if (!customInput.CustomOrchestrationState.AllowActionDateChange)
  {
      //date change not allowed
      throw new Exception();
  }

  DateTime newDate = new DateTime();

  try
  {
      newDate = Convert.ToDateTime(customInput.EventInput);
  }
  catch (Exception ex)
  {
      //Invalid Date format
  }

  CancellationTokenSource newToken = new CancellationTokenSource();
  customInput.OrchestrationContext.CreateTimer(newDate, customInput, newToken.Token);

  customInput.CustomOrchestrationState.TimerCancelationToken?.Dispose();

  CancelCurrentTimer(customInput.CustomOrchestrationState);

  customInput.CustomOrchestrationState.ActionDate = newDate;
  customInput.CustomOrchestrationState.TimerCancelationToken = newToken;

  return customInput.CustomOrchestrationState;
}    

In the SQL database I can see that the new timer is created but the orchestration seems to stay stuck when the new timer should have fired.

image

Is this behavior expected or is it a bug? Any suggestions on how I can debug this issue or any improvements I can implement to get this working.