免責事項:私はErlangとOTPにはかなり新しいです。Erlang:プロセス用の単純なpubsub - 私のアプローチは大丈夫ですか?
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}.
しかし、すべては一見正常に動作するように見える一方で(子供たちがメッセージを受信し、シームレスたときに再起動されます彼らは失敗する)、これは良いアイデアだったたびに私は不思議です。
私のアプローチを批判したり、承認したりすることができますか?
メッセージは保存されており、新規プロセスは購読していますか?それとも、メッセージがプロセスが購読した時点からだけ渡されるのでしょうか? –
後者。 Redisまたは0MQ Pub/Subのようなものです。私は 'gen_event'をもう一度見ていきます。ありがとう。 – drdaeman