我正在寻找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