0

I am working on a Service Fabric project where I need to implement a schedule job that can execute at specific time (say every 16hrs or 24hrs).

Here is my stateful actor service implementation

[StatePersistence(StatePersistence.None)]
internal class Actor3 : Actor, IActor3, IRemindable
{
    public Actor3(ActorService actorService, ActorId actorId): base(actorService, actorId)
    {
    }

    public async Task RegisterReminder()
    {
        try
        {
            var previousRegistration = GetReminder("Reminder2");
            await UnregisterReminderAsync(previousRegistration);
        }
        catch (ReminderNotFoundException) { }
        var reminderRegistration = await RegisterReminderAsync("Reminder2", null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
    }

    public async Task ReceiveReminderAsync(string reminderName, byte[] state, TimeSpan dueTime, TimeSpan period)
    {
        var location = Directory.GetCurrentDirectory();
        var current = DateTime.Now;
        Thread.Sleep(15000);
        using (var writer = File.AppendText("actor.txt"))
        {
            await writer.WriteLineAsync("2 :: " + current.ToString() + " --> " + DateTime.Now.ToString());
    }
    }
}

In the code, I have registered my actor service to start the execution after 1 minute from registration and then execute every 1 minute after that.

When I look at the logs in "actor.txt", what I see is as below:

2 :: 2021-10-11 17:31:15 --> 2021-10-11 17:31:30
2 :: 2021-10-11 17:32:30 --> 2021-10-11 17:32:45
2 :: 2021-10-11 17:33:45 --> 2021-10-11 17:34:00

From above logs, I can be seen that the

  • First execution started at 17:31:15 and completed at 17:31:30 (took 15 secs)
  • Second execution started at 17:32:30 (after 1 minute from end time) and completed at 17:32:45. From above requirement, it should have started at 17:32:15 (since the expected duration is 1 minute between the two execution and not 1 minute + previous execution time.

It seems I am having hard time finding the solution wherein I can make the actor execute at specific time. (i.e. Every day at 4PM or 12AM)

Hiren Desai
  • 941
  • 1
  • 9
  • 33

1 Answers1

0

Consider creating an actor with a reminder that triggers periodically, let's say every minute. (depending on the required accuracy) Inside its state, define the 'due time' that specifies when an action needs to be executed.

Compare the 'due time' with the current time, including a delta. If there's an overlap, execute the task.

Inside the state, store the last execution timestamp to avoid duplicate executions.

Periodically check for missed executions.

This way, you can deal with temporary outages in the cluster (service moves, restarts, upgrades, etc.)

LoekD
  • 11,402
  • 17
  • 27