DaprのアクターでタイマーとリマインダーをJava SDKで使う
概要
前回の記事がこちら。
今回はやり残していたタイマーとリマインダーを見てみます。
タイマーとリマインダーの簡単な説明
タイマーとリマインダーは両方ともアクターの作業をスケジューリングできる機能です。
1度きりの作業と定期的な作業、どちらもスケジューリングできます。
タイマーとリマインダーの違いはスケジューリング後にアクターが非アクティブ化されたときの挙動です。
時間が来た際にアクターが非アクティブ状態の場合、タイマーは動作しませんがリマインダーはアクターをアクティベートして動作してくれます。
リマインダーは状態ストアにスケジュールを保存することでこれを実現しています。
公式ドキュメントによると、軽量でステートレスなタイマーとより多くのリソースを必要とするステートフルなリマインダー、といった表現がされています。
コンテナが落ちてスケジュールが失われても良い場合は軽量なタイマーを、そういった場合でも確実に実行したい場合はリマインダーを、といった使い分けになりそうです。
タイマーとリマインダーをJava SDKで使う方法
アクターの基底クラスであるio.dapr.actors.runtime.AbstractActor
に次の2つのメソッドがあり、それぞれタイマーの登録・解除、リマインダーの登録・解除ができます。
registerActorTimer
unregisterTimer
registerReminder
unregisterReminder
タイマーの登録
registerActorTimer
は5つの引数を取ります。
引数名 | 型 | 説明 |
---|---|---|
timerName |
String |
タイマーの名前。null の場合、自動生成される。 |
callback |
String |
時間が来たら呼び出されるコールバックメソッドの名前。 |
state |
型変数T
|
スケジュールされたコールバックメソッドへ渡す引数。 |
dueTime |
java.time.Duration |
コールバックメソッドの初回呼び出しまでの遅延時間。Duration.ZERO を渡すと即時呼び出しされる。 |
period |
java.time.Duration |
コールバックメソッドを定期的に呼び出す間隔。Duration.ofMillis(-1L) を渡すと定期的な呼び出しはされない。 |
戻り値はMono<String>
でタイマーの名前が返ってきます。
自動生成された場合はこの戻り値で取得できるわけですね。
コード例は次の通り。
public class TimerDemoActorImpl extends AbstractActor
implements TimerDemoActor {
@Override
public Mono<String> doLater(String state) {
// 10分後にhandleDoLaterメソッドを呼び出す。
// その後、30分毎にhandleDoLaterメソッドを呼び出す。
return registerActorTimer(null, "handleDoLater", state,
Duration.ofMinutes(10), Duration.ofMinutes(30));
}
@Override
public void handleDoLater(String state) {
// 遅延実行される。
}
}
リマインダーの登録
registerReminder
は4つの引数を取ります。
引数名 | 型 | 説明 |
---|---|---|
reminderName |
String |
リマインダーの名前。タイマーとは異なりnull を渡しても自動生成されない。 |
state |
型変数T
|
タイマーと同じ。 |
dueTime |
java.time.Duration |
タイマーと同じ。 |
period |
java.time.Duration |
タイマーと同じ。 |
戻り値はMono<Void>
です。
リマインダーはコールバックメソッドを指定しませんが、その代わりにアクターがio.dapr.actors.runtime.Remindable
をimplements
する必要があります。
Remindable
のreceiveReminder
がコールバックメソッドになります。
複数種類のリマインダーを登録したい場合、receiveReminder
に渡されるリマインダーの名前で処理を分岐させることになりそうです。
コード例は次の通り。
public class ReminderDemoActorImpl extends AbstractActor
implements ReminderDemoActor, Remindable<String> {
@Override
public Mono<Void> doLater(String state) {
// 10分後にreceiveReminderメソッドを呼び出す。
// その後、30分毎にreceiveReminderメソッドを呼び出す。
return registerReminder("demo", state,
Duration.ofMinutes(10), Duration.ofMinutes(30));
}
@Override
public TypeRef<String> getStateType() {
// Remindableで宣言されているメソッド。
// リマインダーが受け取るステートの型。
return TypeRef.get(String.class);
}
@Override
public Mono<Void> receiveReminder(String reminderName, String state,
Duration dueTime, Duration period) {
// Remindableで宣言されているメソッド。
// 遅延実行される。
}
}
タイマーとリマインダーの解除
unregisterTimer
メソッドへタイマー名を渡して呼び出せばタイマーを解除できます。
unregisterReminder
メソッドへリマインダー名を渡して呼び出せばリマインダーを解除できます。
以上です。
Discussion