Edited at

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

More than 1 year has passed since last update.

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();
}