2012-04-15 18 views
0

受信したメッセージに応答するいくつかのプロセスを生成したい。これは簡単です。しかし、私はまた、別のプロセスの出力をブロックできるプロセスを用意したいと思っています。Erlangプロセスメッセージの抑制

別の言語では、メッセージを送信する前にフラグを設定し、そのフラグの状態を確認することがあります。しかし、Erlangは可変変数を持っていないので、どうすればそれを達成できますか?

私は確かに抑制メッセージを見るためにreceiveにパターンを追加できます。私はちょうどそれと次に何をするか分からない。

私は本当にこのためにETSテーブルを使用するというアイデアはありません。これは、すばらしい分散モデルを破るためです。同様に、並行性の問題についてもあまり心配していませんが、私はこれを最も適切な方法で設計したいと思います。

+0

は、メッセージを送信するか否かを示すプロセスデータにフラグを保持します。 – rvirding

答えて

2

各エコーサーバーは、現在ミュートされているかどうかを示す独自の状態を持つことができます。他のプロセスは、その状態をミュート/ミュート解除メッセージで切り替えることができます。メッセージに応答する前に、エコーサーバは状態をチェックし、適切に動作します。例えば

1> {ok, Pid} = echo:start_link(). 
{ok,<0.99.0>} 
2> echo:echo(Pid, "this message will be echoed."). 
#Ref<0.0.0.443> 
3> echo:echo(Pid, "as will this message.."). 
#Ref<0.0.0.447> 
4> echo:mute(Pid). 
ok 
5> echo:echo(Pid, "this message will not."). 
#Ref<0.0.0.457> 
6> echo:unmute(Pid). 
ok 
7> echo:echo(Pid, "but this one will.."). 
#Ref<0.0.0.461> 
8> flush(). 
Shell got {#Ref<0.0.0.443>,"this message will be echoed."} 
Shell got {#Ref<0.0.0.447>,"as will this message.."} 
Shell got {#Ref<0.0.0.461>,"but this one will.."} 
ok 
9> echo:stop(Pid). 
ok 

コード:

-module(echo). 

-behaviour(gen_server). 

%% API 
-export([start_link/0, 
    echo/2, 
    mute/1, 
    unmute/1, 
    stop/1]). 

%% gen_server callbacks 
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, 
    terminate/2, code_change/3]). 

-define(SERVER, ?MODULE). 

-record(state, {mute=false}). 

%%%=================================================================== 
%%% API 
%%%=================================================================== 

start_link() -> 
    gen_server:start_link(?MODULE, [], []). 

echo(Pid, Msg) -> 
    Ref = make_ref(), 
    gen_server:cast(Pid, {echo, self(), Ref, Msg}), 
    Ref. 

mute(Pid) -> 
    gen_server:cast(Pid, mute). 

unmute(Pid) -> 
    gen_server:cast(Pid, unmute). 

stop(Pid) -> 
    gen_server:cast(Pid, stop). 

%%%=================================================================== 
%%% gen_server callbacks 
%%%=================================================================== 

init([]) -> 
    {ok, #state{}}. 

handle_call(_Request, _From, State) -> 
    Reply = ok, 
    {reply, Reply, State}. 

handle_cast({echo, From, Tag, Msg}, #state{mute=false} = State) -> 
    From ! {Tag, Msg}, 
    {noreply, State}; 
handle_cast({echo, _From, _Tag, _Msg}, #state{mute=true} = State) -> 
    {noreply, State}; 
handle_cast(mute, State) -> 
    {noreply, State#state{mute=true}}; 
handle_cast(unmute, State) -> 
    {noreply, State#state{mute=false}}; 
handle_cast(stop, State) -> 
    {stop, normal, State}; 
handle_cast(_Msg, State) -> 
    {noreply, State}. 

handle_info(_Info, State) -> 
    {noreply, State}. 

terminate(_Reason, _State) -> 
    ok. 

code_change(_OldVsn, State, _Extra) -> 
    {ok, State}.