gen_server:cast/2 を使用したErlang非同期メッセージ処理の良い例を探しています。
Module:handle_cast/2 を介してリクエストを受信し、それをモジュールのローカル キューに保持し、明示的にメッセージを送信することで、後でリクエストに対応する応答メッセージを送り返す OTP ssh モジュールの例を見てきました。呼び出し元に。読んでみると、コードがほとんど理解できず、アイデアが掴めませんでした。
疑似コードの一部を歓迎します。
gen_server:cast/2 を使用したErlang非同期メッセージ処理の良い例を探しています。
Module:handle_cast/2 を介してリクエストを受信し、それをモジュールのローカル キューに保持し、明示的にメッセージを送信することで、後でリクエストに対応する応答メッセージを送り返す OTP ssh モジュールの例を見てきました。呼び出し元に。読んでみると、コードがほとんど理解できず、アイデアが掴めませんでした。
疑似コードの一部を歓迎します。
ssh_connection_managerモジュールを参照していると思います。
を実行するgen_server:cast/2
と、リクエストはModule:handle_cast/2
関数で処理されます。ここで注意すべき点がいくつかあります。
handle_cast
送信者に関する情報がないため、メッセージ自体の中でこの情報を送信しない限り、結果を送信者に返送することはできません。gen_server:cast/2
、応答を待ちません。実際には、メッセージが到着したかどうかは関係ありません(一部の例外を除く)。handle_cast/2
tupleを返すことができるため、そこに応答を返す方法はありません。そうは言っても、あなたが見ているコードの背後にある考え方は(物事を単純化する)べきです:
gen_server:call/2
が行われますこの時点で、他のクライアント(A)または同じクライアント(B)からの結果を計算するためにさらに情報が必要かどうかに応じて、2つの可能性があります。
gen_server:call/2
。通常、キャストを送信するときに直接の返信を期待することはありません。それ以外の場合は、gen_server:call を使用します。
実際の例として、いくつかの「チャネル」を処理する gen_server があり、エラー ログにチャネル名を追加するために多くの用途があります。チャネル名は、gen_server の状態に格納されます。エラーをログに記録したいプロセスを妨げないようにするために、「名前を取得」同期呼び出しを使用して先頭に追加する名前を取得するのではなく、キャストを使用してメッセージを送信します。
error(Pid, Tags) ->
gen_server:cast(Pid, {log, error_report, Tags}).
warning(Pid, Tags) ->
gen_server:cast(Pid, {log, warning_report, Tags}).
info(Pid, Tags) ->
gen_server:cast(Pid, {log, info_report, Tags}).
キャストは非常に単純なハンドラーで処理され、返されません。
handle_cast({log, Report, Tags}, #state{name=Name}=State) ->
error_logger:Report([{chan, Name} | Tags]),
{noreply, State};
返送する非同期メッセージがある場合、これはキャストの処理とは完全に無関係です。どういうわけか保存しなければならないこれらのメッセージの送信先を知る必要があるかState
、固定名を使用しています。
通常、メッセージを送信するだけでなく、受信プロセス モジュールの関数を呼び出す必要があります (別のキャストまたは単純なメッセージ送信である可能性があります)。