gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 23:42:33 25 4
gpt4 key购买 nike

对我当前的方法不满意,我只是尝试重新设计在 Erlang 中构建协议(protocol)栈的方式。按重要性排序的功能:

  1. 性能

  2. 添加新协议(protocol)变体的灵 active 和实现速度

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

除了通过函数调用的 send() 和通过消息接收的丑陋的不对称性之外,我当前的模型 ( alreday described in this question ) 已达到其极限。

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

底部:

  • 每个堆栈的底部有多个端口,或者有时可能有一个 gen_tcp(独立 channel 有多个相同的堆栈,因此我们不能在这里过于静态地注册进程,必须在各处传递 Pids。

  • 端口顶部是一些由主管管理的模块(随系统启动,并且在整个生命周期内没有错误)。

顶部:

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

  • 协议(protocol)栈的顶端可能只能动态启动,因为堆叠在一起形成堆栈的模块是动态可配置的,并且可能会因连接而异。

  • 当前计划将传递一个模块名称列表 + 可选参数,这些参数会在堆栈中调用 connect() 时使用。

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

模块类型及其之间的通信类型

目前发现的模块有以下几种:

  • 无状态过滤模块

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

层之间的通信类型:

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

  • 同步调用发送一些内容,阻塞直到有答案,然后将结果作为返回值返回。

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

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

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

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

请原谅这个问题的冗长解释,但我认为它仍然普遍用于各种协议(protocol)实现。

我将在答案中写下到目前为止我计划的内容,并且还将解释最终的实现以及我稍后的经验,以便在这里实现一些普遍有用的东西。

最佳答案

我将添加到目前为止我计划的内容作为答案的一部分:

  • connect 传递了一个要堆栈的模块列表,在参数的情况下看起来像一个 proplist,例如:

    connect([module1, module2, {module3, [params3]}], param0, further_params)

    每一层剥离头部并调用下一层连接。

  • connect()“以某种方式”向上和/或向下层传递有趣的引用

    • 发送异步发送堆栈将由较低级别的连接返回
    • 用于异步接收堆栈的recv将作为参数传递给较低级别​​的连接
    • 调用同步发送并等待返回的回复 - 不确定如何处理这些,可能也从较低级别的连接返回
  • 多路复用器路由列表可能如下所示

    connect([module1, multiplexer, [[m_a_1, m_a_2, {m_a_3, [param_a_3]}], 
    [m_b_1, m_b_2],
    [{m_c_1, [param_c_1]}, m_c_2]], param0,
    further_params]).
<小时/>

目前我决定不会有额外的同步调用函数,我只是使用 send 来实现。

在这种情况下,有一个无状态模块的想法的实现示例:encode/1decode/1 对数据包进行一些 for 和 back 转换,例如将二进制表示解析为记录并返回:

connect(Chan, [Down|Rest], [], Recv_fun) ->
{Down_module, Param} = case Down of
{F, P} -> {F, P};
F when is_atom (F) -> {F, []}
end,
Send_fun = Down_module:connect(Chan, Rest, Param,
fun(Packet) -> recv(Packet, Recv_fun) end),
{ok, fun(Packet) -> send(Packet, Send_fun) end}.

send(Packet, Send_fun) ->
Send_fun(encode(Packet)).

recv(Packet, Recv_fun) ->
Recv_fun(decode(Packet)).

一旦我有了一个有状态的示例,我也会发布它。

关于erlang - 如何设计灵活的Erlang协议(protocol)栈创建API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4059746/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com