问题标签 [erlang-otp]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
717 浏览

erlang - Erlang/OTP 框架的 error_logger 在相当高的负载下挂起

我的应用程序基本上是一个基于内容的路由器,它将路由 MMS 事件。

我使用的记录器是SASL模式下OTP框架自带的“ error_logger

问题是::

我正在使用客户端生成具有默认值的 MMS 事件。这个客户端(在 Java 中)能够在多个线程中发送高负载的事件

我在 10 个线程中发送 100 个事件(每个线程发送 10 个 MMS 事件)到我用 Erlang/OTP 编写的路由器。

问题是,当我的路由器收到如此高的负载时,我的 Logger 挂起,即它停止更新我的日志文件。但是路由器仍然能够路由事件。

我得出的结论是::

  1. 当接收到如此高的事件负载(每个事件的单独进程)时,Erlang 中的调度问题。

  2. 一个非常不可能的死锁状态。

  3. 可能是由于在多个线程中发送事件而不是按顺序发送它们。但是我猜一个路由器会连接到多个服务提供者盒子,所以我想到了在线程中发送事件。

任何人都可以帮助 mw 揭开这个问题的神秘面纱吗?

0 投票
1 回答
169 浏览

events - 确保在 Erlang/OTP 中切换 gen_event 处理程序时处理事件

假设我有几个版本的gen_event处理程序,并希望在程序运行时更改它们:

显然,我可以通过删除一个处理程序并添加另一个处理程序来切换它们:

但这留下了竞争条件的可能性;如果error_man在错误的时间接收到一个事件,它不会被记录。或者如果我更改操作的顺序,它将被记录两次,这也是不可取的。我怎样才能确保它被精确地处理一次?

对于这种情况,我可以只有一个处理程序并将日志记录级别保持为State,但假设这是不可接受的。

0 投票
3 回答
3034 浏览

erlang - 带退避的主管

我有一个具有两个工作进程的主管:一个处理与远程服务器的连接的 TCP 客户端和一个处理连接协议的 FSM。

在子进程中处理 TCP 错误会使代码变得非常复杂。所以我宁愿“让它崩溃”,但这有一个不同的问题:当服务器无法访问时,将很快达到最大重启次数,并且主管将与我的整个应用程序一起崩溃,这对于我来说是非常不可取的这个案例。

我想要的是有一个带回退的重启策略;init否则,如果主管知道何时因崩溃而重新启动(即,它作为参数传递给函数)就足够了。我找到了这个邮件列表线程,但是有没有更官方/更好测试的解决方案?

0 投票
1 回答
1121 浏览

erlang - 我可以在 gen_fsm 状态回调中处理任何收到的消息吗?

我注意到发送到 gen_fsm 进程的 pid 的消息在状态回调中作为事件匹配。这只是偶然还是我可以依赖此功能?

通常我希望发送到 gen_fsm 的一般消息会显示在 handle_info/3 回调中,并认为我必须使用 gen_fsm:send_event 重新发送它。

gen_fsm 是否尝试首先将消息与状态回调匹配,然后始终与 handle_info/3 回调匹配?还是仅当它与状态回调子句不匹配时?

但是,当我尝试它时,我的消息似乎根据调试输出被处理了两次。

所以基本上这个问题也可以这样表述:如何正确处理接收到的消息作为 gen_fsm 状态函数中的事件?


澄清:对于这个问题,应该考虑通过传递消息而发生的一些事件。

我知道,在许多情况下,仅通过对 fsm 使用函数调用来使协议可见是更干净的。

我不太确定这是否会改进提到的 gen_fsm 必须适合的当前框架:不同的协议栈,其中每一层调用一个 connect() 函数来附加(有时启动)较低层。数据包通过调用函数(发送)被发送到较低层,并通过receive消息接收。很像 gen_tcp。

通过查看 gen_fsm 的代码,我已经发现一般消息仅传递给 handle_info,因此问题仍然存在,是直接从 handle_info/3 回调调用状态函数还是使用 gen_fsm:send_event 重新发送。

0 投票
1 回答
778 浏览

erlang - 如何设计灵活的 Erlang 协议栈创建 API

对我目前的方法不满意,我只是想重新设计我在 Erlang 中构建协议栈的方式。按重要性排序的特征:

  1. 表现

  2. 添加新协议变体的灵活性和实施速度

  3. 从 shell 探索协议变体将有助于开发

我当前的模型(已经在这个问题中描述过)除了通过函数调用发送()和通过消息接收的丑陋不对称外,已经达到了极限。

整个协议引擎的整体图是这样的:

底部:

  • 在每个堆栈的底部有几个端口,或者有时可能还有一个 gen_tcp(对于独立通道有多个相同的堆栈,所以我们在这里不能太静态,只是注册进程,必须到处传递 Pid。

  • 在端口之上是一些由主管管理的模块(从系统开始,并且在没有错误的情况下保持整个生命周期)。

顶部:

  • 由事件发生触发(在一般意义上不是 event_handler 意义上的)是面向连接的协议端(例如 withconnect()close()语义。

  • 协议栈的顶端可能只能动态启动,因为堆叠在彼此之上以形成堆栈的模块是动态可配置的,并且可能会在连接之间发生变化。

  • 目前计划从顶层传递一个模块名称列表 + 可选参数,这些参数connect()在堆栈中被调用时被消耗。

  • 顶级流程将被链接,因此当这里出现任何问题时,整个连接都会失败。

模块的类型和它们之间的通信类型

目前发现有几种模块:

  • 无状态过滤器模块

  • 具有状态的模块,一些适合 gen_server,一些 gen_fsm,但大多数可能是简单的服务器循环,因为选择性接收将很有用并且经常简化代码。

层之间的通信类型:

  • 独立发送和接收数据包(从外部看是独立的)

  • 发送某些东西的同步调用,阻塞直到有答案,然后将结果作为返回值返回。

  • 与多个模块通信的多路复用器(这是我在这里的定义,以方便讨论)

  • 具有不同连接点(目前由原子命名)的解复用器,用于与面向上的模块进行通信。

目前我唯一的解复用器位于堆栈的静态底部,而不是动态创建的顶部。多路复用器目前仅在顶部。

在我之前链接的问题处理的答案和评论中,我听说通常 API 应该只包含函数而不是消息,我同意这一点,除非另有说服力。

请原谅对问题的冗长解释,但我认为它仍然适用于各种协议实现。

我将在答案中写下我迄今为止计划的内容,还将解释最终的实现和我稍后的经验,以便在这里实现通常有用的东西。

0 投票
3 回答
4160 浏览

erlang - 如何在 Erlang/OTP 中使用 application:get_env()?

我创建了一个 mochiweb 实例

myserver_web.erl我能够访问应用程序配置

但是room.erl,我无法访问应用程序配置(特别是env列表)。

主管没有启动房间,我也不想要它。

我是 OTP 的新手,我意识到我可能在做一些愚蠢的事情,但我非常感谢任何人的帮助。

干杯!

0 投票
2 回答
1700 浏览

erlang - 如何找到 OTP 流程的主管?

是否有功能可以让 OTP 进程找到其主管的 pid?

0 投票
3 回答
2358 浏览

erlang - Java 到 Erlang 的消息

我正在用 Java 中的 GUI 用 Erlang 制作一个应用程序。我已经设法在 to 语言之间建立了连接,但现在我需要(我猜)每次按下按钮时从 Java 向 Erlang 发送一条消息。

这是正确的方法吗?

这样的消息会是什么样子?

我找到了一些关于这种集成形式的好网站,但我觉得我没有得到一切。

http://www.trapexit.org/How_to_communicate_java_and_erlang

0 投票
2 回答
617 浏览

erlang - gen_fsm 初始状态,在生成时向其发送事件

如果我想在生成它时始终将事件发送到 gen_fsm 的初始状态,我应该在哪里调用该函数?就在 start_link 之后或从首先调用 start_link 的进程开始。这里有什么最佳实践吗?

0 投票
1 回答
507 浏览

erlang - 工作进程死亡时的数据持久性,如何?

我有需要收集/计算的数据作为启动参数的工作进程。然后在重新启动时也需要这样做。我应该把初始化代码放在哪里?在主管初始化内部?还是在模块 start_link 或 init 内部?Erlang 在这方面有什么最佳实践吗?