我正在尋找erlang的好例子異步使用gen_server處理消息:cast/2。使用gen_server處理Erlang異步消息:cast/2
我見過的OTP SSH模塊,它接收到一個請求通過 模塊中的一個示例:handle_cast/2,它保持在模塊的一個本地隊列,後來發回對應於該請求的應答消息,通過明確地向呼叫者發送消息。當我試圖閱讀它時,我幾乎無法跟蹤代碼,並且無法理解這個想法。
讚賞一段僞代碼。
我正在尋找erlang的好例子異步使用gen_server處理消息:cast/2。使用gen_server處理Erlang異步消息:cast/2
我見過的OTP SSH模塊,它接收到一個請求通過 模塊中的一個示例:handle_cast/2,它保持在模塊的一個本地隊列,後來發回對應於該請求的應答消息,通過明確地向呼叫者發送消息。當我試圖閱讀它時,我幾乎無法跟蹤代碼,並且無法理解這個想法。
讚賞一段僞代碼。
我相信你指的是ssh_connection_manager模塊。
執行gen_server:cast/2
時,將在Module:handle_cast/2
函數中處理該請求。幾件事情要注意這裏:
handle_cast
參數你沒有有關發件人的信息,所以你不能 - 除非你發送郵件本身這個信息 - 發回了一些成績吧。gen_server:cast/2
後,不會等待回覆。實際上,它甚至不關心消息是否到達(有一些例外)。handle_cast/2
,你可以返回一個noreply或停止元組,所以沒辦法返回一個答覆那裏。說,你一直在尋找的應該(簡化的東西)的代碼背後的想法:
gen_server:call/2
由在這一點上,你有兩種可能,這取決於如果你需要更多的信息來計算從其他客戶端(A)你的結果或來自同一客戶(B):
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
中,或者您使用的是固定名稱。
通常情況下,你不應該只是發送一條消息,而是調用接收處理模塊的函數(這可能是另一個強制轉換或簡單的消息發送)。
感謝您的解釋。 – jj1bdx 2011-06-15 12:46:32
這似乎說明它cast'和'call''之間的差異:http://bytefilia.com/gen_server-synchronous-vs-asynchronous/ – Stratus3D 2014-06-27 19:41:02