- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在浏览 erlang 应用程序的代码时,我遇到了一个有趣的设计问题。让我描述一下情况,但由于 PIA,我无法发布任何代码,抱歉。
代码结构为 OTP 应用程序,其中两个 gen_server
模块负责分配某种资源。该应用程序完美运行了一段时间,我们并没有遇到大问题。
当第一个 gen_server
需要检查第二个是否有足够的资源时,棘手的部分就开始了。向第二个 gen_server 发出一个 call
,它本身调用一个实用程序库(在非常非常特殊的情况下)向第一个 gen_server 发出一个 call
。
我对 erlang 比较陌生,但我认为这种情况会使两个 gen_server 互相等待。
这可能是一个设计问题,但我只是想知道 OTP 中是否有任何内置的特殊机制可以防止这种“挂起”。
如有任何帮助,我们将不胜感激。
编辑:总结答案:如果您遇到两个 gen_server
call
以循环方式相互调用的情况,您最好在应用程序设计上多花些时间。
感谢您的帮助:)
最佳答案
这称为死锁,可以/应该在设计层面避免。下面是一个可能的解决方法和一些主观观点,希望能帮助您避免犯错。
虽然有多种方法可以解决您的问题,但“等待”正是 call
正在做的事情。
一种可能的解决方法是从 A 内部生成一个调用 B 的进程,但不会阻止 A 处理来自 B 的调用。该进程将直接回复调用者。
在服务器 A 中:
handle_call(do_spaghetti_call, From, State) ->
spawn(fun() -> gen_server:reply(From, call_server_B(more_spaghetti)) end),
{noreply, State};
handle_call(spaghetti_callback, _From, State) ->
{reply, foobar, State}
在服务器 B 中:
handle_call(more_spaghetti, _From, State) ->
{reply, gen_server:call(server_a, spaghetti_callback), State}
对我来说,这是非常复杂且极难推理的。我认为您甚至可以在不冒犯任何人的情况下将其称为意大利面条代码。
另一方面,虽然上述方法可能会解决您的问题,但您应该仔细考虑这样的调用实际上意味着什么。例如,如果服务器 A 多次执行此调用会怎样?如果在任何时候超时会发生什么?您如何配置超时以使它们有意义? (最内层调用的超时时间必须比外层调用短,等等)。
我会改变设计,即使这很痛苦,因为当你允许它存在并解决它时,你的系统就会变得很难推理。恕我直言,复杂性是万恶之源,应不惜一切代价避免。
关于erlang - 解决两个 gen_tcp 之间的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6036969/
我想将主机名和端口从命令行传递给 gen_tcp.connect。 defmodule MyComm.Application do use Application def main(args
在浏览 erlang 应用程序的代码时,我遇到了一个有趣的设计问题。让我描述一下情况,但由于 PIA,我无法发布任何代码,抱歉。 代码结构为 OTP 应用程序,其中两个 gen_server 模块负责
这个问题在这里已经有了答案: Erlang server, Java client - TCP messages get split? (3 个回答) 7年前关闭。 我正在使用 this 中的 soc
有没有办法从 Erlang 中的套接字读取整行,或者我是否需要在 gen_tcp:recv 之上手动实现行缓冲? ? 最佳答案 你有没有试过使用 inet:setopts(Socket, [{pack
我修改了 this server使用 gen_tcp:recv为了将数据包的字节数限制为 50。我注释掉了行 inet:setopts(Socket, [{active, once}]),因为 gen
我很感兴趣 gen_tcp:accept 函数的限制是什么?我的意思是什么是最大并发连接数?或者如何配置? (gen_tcp 设置、ulimit 或其他)get_tcp 每秒可以接受多少连接? 最佳答
简单的问题... 这段代码.. client() -> SomeHostInNet = "localhost" % to make it runnable on one machine
我写了一个简单的http客户端,遇到以下问题,我复制粘贴了do_recv来自官方文档,但它的工作方式很奇怪: do_recv(Sock, Bs) -> case gen_tcp:recv(So
我们有一个 gen_server 进程,它通过创建被动套接字并将其借用给其他进程来管理客户端的被动套接字池。任何其他进程都可以借用套接字,使用该套接字向服务器发送请求,通过 gen_tcp:recv
我有一个监听 Ip:Port 的 TCP 服务器。 listen(Ip, Port) -> Opts = [ binary, {active, false}, {packe
我正在实现一个接受许多并发连接的服务器。 我使用了这个结构: loop(Sock) -> case gen_tcp:accept(Sock) of {ok, CSock} ->
我正在尝试学习 Erlang 来做一些简单但可扩展的网络编程。我基本上想编写一个程序来完成互联网 Backbone 上的服务器所做的事情——但规模较小。我想尝试建立一个带有 Web 可访问服务器的 I
在我输入 gen_ 然后在 erlang shell 中输入 Tab 后,我得到了 gen_server、gen_event,但我没有得到gen_tcp。如何在 Erlang shell 中使用 ge
下面是解释如何使用 gen_tcp 的一个示例的一部分。然而,几乎所有的教程都只会向您展示一个回显服务器,而不会解析真实世界的 HTTP 请求。 handle_connect(Socket,
如何使用 gen_tcp 在 erlang 中发送形式为 [Integer, String] 的消息。 例如:我希望使用 gen_tcp:send/2 通过套接字发送形式为 [25, "Hello"]
我遇到了一个问题。我在 Erlang/OTP 上有一个 iOS 客户端和一个 tcp 服务器。客户端假设通过 GCDAsynchSocket 向服务器发送和接收消息。如果我需要发送消息但它不能作为接受
我正在尝试使用 Erlang gen_tcp 在 Elixir 中通过 TCP 连接接受数据 {:ok, socket} = :gen_tcp.connect("127.0.0.1" ,2000,[:
一些教程,包括这个 Learn You Some Erlang一,显示 OTP 主管将打开并拥有一个 TCP 监听套接字并将其共享给将接受连接的多个工作人员的应用程序。 我的问题是,如何在没有 ter
我正在尝试使用 gen_tcp 模块。有服务器端代码的示例,我遇到了麻烦。 %% First, I bind server port and wait for peer connection {ok,
编辑于 2015-11-25 02:10 我的 ejabberd 版本是 14.12 和 erlang R17B,所以这段代码似乎没用,因为 R17B 中的 erlang:system_info(ot
我是一名优秀的程序员,十分优秀!