如果您想让一个进程向另一个进程发送消息,很明显您需要两个进程。当 Yaws 收到 HTTP 请求时,默认情况下它会将请求分派到其 Erlang 进程池中的进程之一。当您在示例中使用.yaws 文件时,该过程会调用您的out/1 函数。但这只是一个过程,所以您需要另一个过程。
有很多方法可以启动第二个进程。一种简单的方法是spawn_link 一个进程运行任何逻辑将消息发送到loop/1:
<erl>
out(_Arg) ->
process_flag(trap_exit, true),
Self = self(),
Pid = spawn_link(fun() -> my_business_logic(Self) end),
loop(Pid).
loop(Pid) ->
receive
{Pid, good} -> {html, "Good"};
{Pid, bad} -> {html, "Bad"};
{'EXIT', Pid, Reason} ->
[{status, 500},
{html, "internal server error"}]
end.
my_business_logic(Parent) ->
%% run your logic here, then send a message
Parent ! {self(), good}.
</erl>
请注意,我们将子进程Pid 放入消息中以识别它源自预期进程。另请注意,我们链接到子进程并陷阱退出,以便如果子进程意外死亡,我们可以捕获EXIT 并正确报告错误。
但这可能不是一个好方法。如果逻辑进程应该独立于任何 HTTP 请求运行,您可以在 Erlang 系统启动时启动它们的池,并让 out/1 函数发送一条消息,要求它代表它执行请求。这完全取决于这些进程在做什么、它们与传入请求的关系以及拥有它们的池是否足以满足您期望的请求负载。
使用.yaws 文件对某些应用程序来说很方便,但它们可能会受到限制。另一种方法是构建一个包含 Yaws 和您自己的应用程序的 Erlang 系统,并使用 Yaws appmod feature 让 Yaws 将请求分派到您自己的运行您自己的 Erlang 模块的进程中。在这里解释所有这些是不切实际的,所以请咨询Yaws documentation或Yaws book,或向Yaws mailing list寻求帮助。