シングルスレッドキューとしてのScalaアクター
-
05-07-2019 - |
質問
プログラムでアクターを使用したいのですが、アクターのいくつかをキューのように扱うことに関して何らかの制限があります。たとえば、変更イベントが適用される外部システムと、外部システムのデータのキャッシュがあるとします。だから私には2人の俳優がいます:
-
ChangeApplicationActor
-
CacheActor
ChangeApplicationActor
の一部として、外部システムのエンティティ X
に変更を適用するときに、 CacheActorに通知するイベントを送信したい
同期する:
val changeApplicationActor = actor {
loop {
react {
case ChangeInstruction(x) =>
externalSystem.applyChange(x)
cacheActor ! Sync(x)
}
}
}
ただし、2つの要件があります:
-
CacheActor
には内部状態があり、理想的にはSync
命令を順次処理したいです -
x
の同じ値に対して2つのSync(x)
命令を含むCacheActor
の受信トレイになった場合、 2番目のものを無視したい(つまり、x
の特定の値に対して保留中のSync
命令を1つだけ持つ必要がある)
アクターを強制的にシングルスレッドにする方法はありますか?アクターのメールボックスにアクセスして、重複するイベントを削除する方法はありますか? CacheActor
を、アクターではなく として実装することを避けられませんか?
解決
アクターは一度に1つのスレッドでのみ実行されることが保証されており、アクターのメールボックス内のメッセージはFIFO順であるため、#1があります。
2には組み込みのサポートがないため、扱いにくいです。アクターには「メールボックス」という属性があります。受信または反応を介さずに、メールボックスに直接アクセスできます。メッセージの処理が完了する前に、メールボックスから一致するSyncメッセージをプルコールするだけです。これを行う場合、メッセージ送信中に別のスレッドがメールボックスへの追加を試行しないように、アクターで同期する必要があります。
アクターで同期をとると、ライブラリが行うデッドロックの自由の保証がなくなり、スケーラビリティが低下することに注意してください。しかし、実用的な観点からは、おそらく大丈夫でしょう。
所属していません StackOverflow