LoginSignup
2
1

More than 5 years have passed since last update.

Azure ServiceFabric - ActorのTimerやAlarmを自動で起動

Last updated at Posted at 2017-05-25

Actorはいずれかの処理が呼ばれた場合にActiveになる。
そのため、初回起動時は何かしらの処理を実行しない限りTimerやAlarmも起動しない。

ActorServiceクラスを拡張することで、初回起動時にTimerやAlarmを起動させることができる。

ActorのOnActivyAsyncメソッド内にTimerやAlarmの起動処理を追加する

OnActive内でTimerやAlarmを起動する。(下記の例はAlarm)
(2017/08/30追記 現状原因不明だがアップデート時に前回起動のreminderが終了していない場合があるため残っていたら終了させる)

HogeActorService.cs
protected override async Task OnActivateAsync()
{
    ActorEventSource.Current.ActorMessage(this, "Actor activated.");
    try
    {
        var registerReminder = GetReminder(RequestLimitDataActorName);
        await UnregisterReminderAsync(registerReminder);
    }
    catch (ReminderNotFoundException) 
    { // 処理なし }
    var reminder = await this.RegisterReminderAsync(
                  "Hoge Actor",
                  null,
                  TimeSpan.FromMilliseconds(0),
                  TimeSpan.FromMinutes(10)
                );
}

ActorServiceを拡張したクラスを作成

ActorServiceを拡張し、RunAsyncメソッド内で起動時に呼び出すActorのメソッドをコール

HogeActorService.cs
    public class HogeActorService : ActorService
    {
        public HogeActorService (StatefulServiceContext context, 
                                                         ActorTypeInformation actorTypeInfo, 
                                                         Func<ActorService, ActorId, ActorBase> actorFactory = null,
                                                         Func<ActorBase, IActorStateProvider, IActorStateManager> stateManagerFactory = null,
                                                         IActorStateProvider stateProvider = null, 
                                                         ActorServiceSettings settings = null) 
            : base(context, actorTypeInfo, actorFactory, stateManagerFactory, stateProvider, settings)
        { }


            protected async override Task RunAsync(CancellationToken cancellationToken)
            {
                await base.RunAsync(cancellationToken);
                var proxy = ActorProxy.Create<IHogeActor>(new ActorId(0));
                    // 起動時にに呼び出すActorのメソッドをコール
                await proxy.HogeHoge();
            }
    }

独自のActorServieを利用するように変更

Mainメソッド内で利用しているActorServiceを独自のものに変更
変更前

private static void Main()
{
    try
    {
        ActorRuntime.RegisterActorAsync<HogeActor>(
                   (context, actorType) => new ActorService(context, actorType)).GetAwaiter().GetResult();

        Thread.Sleep(Timeout.Infinite);
    }
    catch (Exception e)
    {
        ActorEventSource.Current.ActorHostInitializationFailed(e.ToString());
        throw;
    }
}

変更後 (2017/05/30 起動時にエラーとなるため修正)

private static void Main()
{
    try
    {
        ActorRuntime.RegisterActorAsync<HogeActor>(
                   (context, actorType) => new HogeActorService(context, actorType, (service, id) => new HogeActor(service, id))).GetAwaiter().GetResult();

        Thread.Sleep(Timeout.Infinite);
    }
    catch (Exception e)
    {
        ActorEventSource.Current.ActorHostInitializationFailed(e.ToString());
        throw;
    }

(2017/06/17追記) Alarmの終了処理を記述(終了処理の記述がないと、更新のデプロイ時に失敗するので必ず終了処理を記述)

        protected override async Task OnDeactivateAsync()
        {
            var register = GetReminder("Hoge Actor");
            await UnregisterReminderAsync(register);

            await base.OnDeactivateAsync();
        }
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1