Erlang/OTP : Synchronous vs. 异步消息传递

标签 erlang erlang-otp

Erlang 最开始吸引我的地方之一是 Actor 模型。不同进程同时运行并通过异步消息传递进行交互的想法。

我刚刚开始深入了解 OTP,尤其是查看 gen_server。我见过的所有示例 - 并且授予它们是教程类型的示例 - 使用 handle_call()而不是 handle_cast()实现模块行为。

我觉得这有点令人困惑。据我所知,handle_call是一个同步操作:调用者被阻塞直到被调用者完成并返回。这似乎与异步消息传递理念背道而驰。

我即将启动一个新的 OTP 应用程序。这似乎是一个基本的架构决策,所以我想在开始之前确保我理解。

我的问题是:

  • 在实际操作中,人们是否倾向于使用 handle_call而不是 handle_cast ?
  • 如果是这样,当多个客户端可以调用同一个进程/模块时,对可扩展性的影响是什么?
  • 最佳答案

  • 取决于你的情况。

    如果你想得到结果,handle_call真的很常见。如果您对通话结果不感兴趣,请使用 handle_cast .当handle_call被使用,调用者会阻塞,是的。这大部分时间都可以。让我们看一个例子。

    如果您有一个将文件内容返回给客户端的 Web 服务器,那么您将能够处理多个客户端。每个客户端都必须等待文件内容被读取,所以使用 handle_call在这种情况下会很好(除了愚蠢的例子)。

    当您确实需要发送请求、进行一些其他处理然后稍后获得回复的行为时,通常会使用两次调用(例如,一次强制转换和一次调用以获取结果)或正常的消息传递。但这是一个相当罕见的情况。
  • 使用 handle_call将在通话期间阻止该过程。这将导致客户排队等待回复,因此整个事情将按顺序运行。

    如果你想要并行代码,你必须编写并行代码。唯一的方法是运行多个进程。

  • 所以,总结一下:
  • 使用 handle_call将阻塞调用者并在调用期间占用调用的进程。
  • 如果您希望并行事件继续进行,则必须并行化。做到这一点的唯一方法是启动更多进程,然后突然调用与强制转换不再是一个大问题(事实上,调用更舒服)。
  • 关于Erlang/OTP : Synchronous vs. 异步消息传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6031910/

    相关文章:

    unit-testing - 多个应用程序出现 Eunit 错误

    erlang - 监督具有相同模块/不同参数的多个 gen_servers

    erlang - Cowboy HTTP POST 处理程序

    elixir - 如何在 GenServer 中执行对当前进程的调用?

    erlang - 是否可以自动重启被杀死的 erlang 应用程序?

    erlang - Thrift/Erlang 字符串

    elixir - 如何生成带参数的匿名函数?

    erlang - 如何自动删除动态主管中已终止子项的规范

    macros - Erlang 中的一等模式?

    erlang - membase 对于 erlang 玩家服务器来说是一个很好的持久层吗?