对我目前的方法不满意,我只是想重新设计我在 Erlang 中构建协议栈的方式。按重要性排序的特征:
表现
添加新协议变体的灵活性和实施速度
从 shell 探索协议变体将有助于开发
我当前的模型(已经在这个问题中描述过)除了通过函数调用发送()和通过消息接收的丑陋不对称外,已经达到了极限。
整个协议引擎的整体图是这样的:
底部:
在每个堆栈的底部有几个端口,或者有时可能还有一个 gen_tcp(对于独立通道有多个相同的堆栈,所以我们在这里不能太静态,只是注册进程,必须到处传递 Pid。
在端口之上是一些由主管管理的模块(从系统开始,并且在没有错误的情况下保持整个生命周期)。
顶部:
由事件发生触发(在一般意义上不是 event_handler 意义上的)是面向连接的协议端(例如 with
connect()
和close()
语义。协议栈的顶端可能只能动态启动,因为堆叠在彼此之上以形成堆栈的模块是动态可配置的,并且可能会在连接之间发生变化。
目前计划从顶层传递一个模块名称列表 + 可选参数,这些参数
connect()
在堆栈中被调用时被消耗。顶级流程将被链接,因此当这里出现任何问题时,整个连接都会失败。
模块的类型和它们之间的通信类型
目前发现有几种模块:
无状态过滤器模块
具有状态的模块,一些适合 gen_server,一些 gen_fsm,但大多数可能是简单的服务器循环,因为选择性接收将很有用并且经常简化代码。
层之间的通信类型:
独立发送和接收数据包(从外部看是独立的)
发送某些东西的同步调用,阻塞直到有答案,然后将结果作为返回值返回。
与多个模块通信的多路复用器(这是我在这里的定义,以方便讨论)
具有不同连接点(目前由原子命名)的解复用器,用于与面向上的模块进行通信。
目前我唯一的解复用器位于堆栈的静态底部,而不是动态创建的顶部。多路复用器目前仅在顶部。
在我之前链接的问题处理的答案和评论中,我听说通常 API 应该只包含函数而不是消息,我同意这一点,除非另有说服力。
请原谅对问题的冗长解释,但我认为它仍然适用于各种协议实现。
我将在答案中写下我迄今为止计划的内容,还将解释最终的实现和我稍后的经验,以便在这里实现通常有用的东西。