如何使用 'Ac­tor Remin­der' 机制在服务结构中安排任务?

How to schedule a task in service fabric using 'Ac­tor Remin­der' mechanism?

我想每天、每周和每月生成发票并定期发送发票。 每个客户都有不同的发票设置。

对于计划任务,您可以使用外部机制,例如 hangfire

它执行与 Web 应用程序不同的计划任务,您可以从其任务仪表板跟踪任务。

您可以注册这样的工作:

RecurringJob.AddOrUpdate(() => SoccerDataFetcher_UpdatePlayersOfTeams(), Cron.Daily);

前段时间我想知道自己该怎么做。基于优秀documentation I came up with a sample app, see my repo.

您的 actor 应该实现 IRemindable 接口。 要创建提醒,请在 actor 方法中使用它:

await RegisterReminderAsync(
            "MyReminder", // name of the reminder
            Encoding.ASCII.GetBytes(message), // byte array with payload (message is a string in my case)
            dueTime, // When is the reminder first activated
            snoozeTime); // Interval between activations

在您的情况下,将 snoozeTime 设置为一天或一周,以便在每个时间段激活提醒。

当到期时间到了时,调用方法 ReceiveReminderAsync

public Task ReceiveReminderAsync(string reminderName, byte[] state, TimeSpan dueTime, TimeSpan period)
{
    ActorEventSource.Current.Message($"Actor recieved reminder {reminderName}.");

    ...
}

您可以通过ReceiveReminderAsync的值来判断它是关于哪个提醒的,您可以使用state的内容来对负载进行操作。

要取消提醒,请使用 UnregisterReminderAsync 方法:

await UnregisterReminderAsync(GetReminder("MyReminder"));  
internal class InvoiceGenerationActor : Actor, IInvoiceGenerationActor, IRemindable
{
    protected override async Task OnActivateAsync()
    {
        ////ActorEventSource.Current.ActorMessage(this, "Actor activated.");

        //// The StateManager is this actor's private state store.
        //// Data stored in the StateManager will be replicated for high-availability for actors that use volatile or persisted state storage.
        //// Any serializable object can be saved in the StateManager.
        //// For more information, see https://aka.ms/servicefabricactorsstateserialization

        //// return this.StateManager.TryAddStateAsync("count", 0);

        ////var schedulerDtos = GetSchedulerList();

        await base.OnActivateAsync();

        ActorEventSource.Current.ActorMessage(this, "Actor activated.");

        IActorReminder generationReminderRegistration = await this.RegisterReminderAsync(GenerationRemainder, BitConverter.GetBytes(100), TimeSpan.FromMilliseconds(0), TimeSpan.FromMinutes(10));

        ////IActorReminder mailReminderRegistration = await this.RegisterReminderAsync(generationRemainder, BitConverter.GetBytes(100), TimeSpan.FromMinutes(1), TimeSpan.FromHours(1));

        return;
    }

    public async Task ReceiveReminderAsync(string reminderName, byte[] context, TimeSpan dueTime, TimeSpan period)
    {
        if (reminderName.Equals(GenerationRemainder))
        {
            await GetAllInvoiceSettingAndRegisterNewRemiders();
        }
        else
        {
            int solutionPartnerId = BitConverter.ToInt32(context, 0);
            var data = await Get("SolutionOwnerInvoiceGeneration/AutomaticInvoiceGeneration/" + solutionPartnerId, "PartnerService");
            await UnregisterReminderAsync(GetReminder(reminderName));
        }
    }
}