免責事項: 私は Erlang と OTP にかなり慣れていません。
Erlang/OTP で単純な pubsub が必要です。プロセスは「ハブ」でサブスクライブし、そのハブに送信されたメッセージのコピーを受信できます。
については知ってgen_event
いますが、イベントを 1 つのイベント マネージャー プロセスで処理する一方で、すべてのサブスクライバーを個別の自律的なプロセスにしたいと考えています。また、私はgen_event
のハンドラーの監督を理解することができませんでした。残念ながら、Google の結果は XMPP (Ejabberd) と RabbitMQ のリンクでいっぱいだったので、私のアイデアに関連するものは何も見つかりませんでした。
私の考えでは、そのような pubsub モデルは監視ツリーにシームレスにマップされます。そこで、スーパーバイザー (gen_server
フードの下) を拡張して、そのすべての子にキャスト メッセージを送信できるようにすることを考えました。
私はこれを私の手っ取り早いカスタム「ディスパッチャー」動作でハッキングしました。
-module(dispatcher).
-extends(supervisor).
-export([notify/2, start_link/2, start_link/3, handle_cast/2]).
start_link(Mod, Args) ->
gen_server:start_link(dispatcher, {self, Mod, Args}, []).
start_link(SupName, Mod, Args) ->
gen_server:start_link(SupName, dispatcher, {SupName, Mod, Args}, []).
notify(Dispatcher, Message) ->
gen_server:cast(Dispatcher, {message, Message}).
handle_cast({message, Message}, State) ->
{reply, Children, State} = supervisor:handle_call(which_children, dummy, State),
Pids = lists:filter(fun(Pid) -> is_pid(Pid) end,
lists:map(fun({_Id, Child, _Type, _Modules}) -> Child end,
Children)),
[gen_server:cast(Pid, Message) || Pid <- Pids],
{noreply, State}.
ただし、一見するとすべてがうまく機能しているように見えますが (子供はメッセージを受信し、失敗するとシームレスに再起動されます)、これが良いアイデアだったのはいつなのだろうかと思います。
誰かが私のアプローチを批判 (または承認) してくれませんか?