2

私は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>たアプリケーションで利用できるようになることも私の意図です。StormTrooperEmperor

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が.ProcessProcess

これが与えられたバックストーリー/セットアップであるため、「アクター/スーパーバイザーの階層」がどうあるべきかを特定できません。私のユースケースでは、すべてのアクターは真に平等であり、アクター間に監視構造はないようです。そのタイプのアクターが存在するように構成されている場合、StormTrooper単にメッセージを受け取ります。Process他のアクター サブクラスについても同様です。

ここで何かが完全に欠けていますか?すべてのアクターが等しく、階層が本質的に「フラット」/水平である場合、(フォールト トレランスの目的で) 監視階層を定義するにはどうすればよいですか?

4

2 に答える 2

1

あなたのコメントに基づいて、アクターにesMasterを複製して配布してもらいたいと考えています。Process概念的には、ユーザー (または入力を生成するもの) がアクターごとに同じ入力を提供することはありません。彼らは一度だけメッセージを提供し、あなた (またはMasterアクター) は必要に応じてメッセージを複製し、適切な子アクターのそれぞれに送信します。

dk14 の回答で説明したように、このアプローチには、耐障害性が向上するという追加の利点があります。

于 2015-04-23T15:07:15.387 に答える