私はAkka(Java lib、v2.3.9)を初めて使用しています。スーパーバイザー階層のベスト プラクティスに従おうとしていますが、これが初めての Akka アプリであるため、どこかで精神的な障壁にぶつかっています。
私の初めての Akka アプリ (実際には、複数のアプリ間での再利用を目的としたライブラリ) では、外界からの入力はProcess
、アクターに渡されるメッセージとして現れます。Process
私のアプリを使用する開発者は、最終的にどのアクターがインスタンスを送信し、どのアクターが送信しないかを構成するテキストベースの構成ファイルを提供します。つまり、これらが私のアクター クラスであるとします。
// Groovy pseudo-code
class Process {
private final Input input
Process(Input input) {
super()
this.input = deepClone(input)
}
Input getInput() {
deepClone(this.input)
}
}
class StormTrooper extends UntypedActor {
@Override
void onReceive(Object message) {
if(message instanceof Process) {
// Process the message like a Storm Trooper would.
}
}
}
class DarthVader extends UntypedActor {
@Override
void onReceive(Object message) {
if(message instanceof Process) {
// Process the message like Darth Vader would.
}
}
}
class Emperor extends UntypedActor {
@Override
void onReceive(Object message) {
if(message instanceof Process) {
// Process the message like the Emperor would.
}
}
}
// myapp-config.json -> where the actors are configured, along with other
// app-specific configs
{
"fizzbuzz": "true",
"isYosemite": "false",
"borderColor": "red",
"processors": [
"StormTrooper",
"Emperor"
]
}
構成ファイルでわかるように、メッセージを受信するためにStormTrooper
とのみEmperor
が選択されました。Process
これにより、最終的にゼロ (0)DarthVader
アクターが作成されます。また、これにより、次のように取り込まれSet<ActorRef>
たアプリケーションで利用できるようになることも私の意図です。StormTrooper
Emperor
class SomeApp {
SomeAppConfig config
static void main(String[] args) {
String configFileUrl = args[0] // Nevermind this horrible code
// Pretend here that configFileUrl is a valid path to
// myapp-config.json.
SomeApp app = new SomeApp(configFileUrl)
app.run()
}
SomeApp(String url) {
super()
config = new SomeAppConfig(url)
}
void run() {
// Since the config file only specifies StormTrooper and
// Emperor as viable processors, the set only contains instances of
// these ActorRef types.
Set<ActorRef> processors = config.loadProcessors()
ActorSystem actorSystem = config.getActorSystem()
while(true) {
Input input = scanForInput()
Process process = new Process(input)
// Notify each config-driven processor about the
// new input we've received that they need to process.
processors.each {
it.tell(process, Props.self()) // This isn't correct btw
}
}
}
}
UntypedActor
したがって、(願わくば) ご覧のとおり、メッセージを処理するこれらすべてのアクター (実際には何十ものimpl) があります (次に、何らかのソースからProcess
取得します)。Input
これらのProcess
メッセージを処理するためにどのアクターが生きている/オンラインであるかについては、完全に構成主導型です。最後に、アプリInput
が.Process
Process
これが与えられたバックストーリー/セットアップであるため、「アクター/スーパーバイザーの階層」がどうあるべきかを特定できません。私のユースケースでは、すべてのアクターは真に平等であり、アクター間に監視構造はないようです。そのタイプのアクターが存在するように構成されている場合、StormTrooper
単にメッセージを受け取ります。Process
他のアクター サブクラスについても同様です。
ここで何かが完全に欠けていますか?すべてのアクターが等しく、階層が本質的に「フラット」/水平である場合、(フォールト トレランスの目的で) 監視階層を定義するにはどうすればよいですか?