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

2023-11-25

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

  1. 表现

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

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

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

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

底部部分:

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

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

顶部部分:

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

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

  • 目前计划将传递一个模块名称列表+来自顶层的可选参数,这些参数在connect()在堆栈中调用。

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

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

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

  • 无状态过滤模块

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

层间通信类型:

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

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

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

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

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

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

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

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


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

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

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

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

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

    • send for async 向下发送堆栈将由较低级别的连接返回
    • 用于异步接收堆栈的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/1 and decode/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)).

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何设计灵活的Erlang协议栈创建API 的相关文章

  • 零部署 CouchDB 嵌入 Windows 应用程序?

    我可能在这里做梦 但我想知道是否有可能将最小的 CouchDB 引擎完全嵌入到 Windows 应用程序中 以便该应用程序可以运行而无需在用户计算机上安装 CouchDB Erlang 我已经提供了这种精简 捆绑的功能 请在此处查看http
  • 为什么 Swift 中委托方法需要公开?

    我正在快速开发一个框架 我正在创建一个处理框架中 BLE 内容的类 这个类应该是公共的 因为我需要从使用我的框架的外部应用程序访问这个类 我的班级结构如下 public class MyClass NSObject CBCentralMan
  • Erlang 更好地支持哪种数据库(SQL)?

    你建议我在 Erlang 中使用什么 MySQL 还是 Postgres 哪个数据库有更好 更成熟 更稳定 更快 的 Erlang 驱动程序 The Erlang ODBC 接口 http erlang org doc apps odbc
  • 如何通过 SSL 从 Phoenix Web App 连接到 PostgreSQL?

    When trying to run Elixir Phoenix Web Application using PostgreSQL Database hosted 3rd party Database as a Service Azure
  • 设置 Emacs 进行 Erlang 编程

    Emacs 是 Erlang 编程的首选 IDE 有很多好的模式 distel erlware mode 默认的 erlang 模式 但是您对设置 Emacs 进行专业 Erlang 开发有何建议 按照中所述设置 erlang mode自述
  • Swift:协议、结构、类

    我开始学习 Swift 语言 但在理解协议 结构和类方面遇到了困难 我来自 Android 方面的编程 所以我相信 Swift 协议基本上是 Java 接口 其中每一个的正确用例是什么 这些类比并不 完全 正确 但这就是我所理解的要点 是的
  • 在 digraph_utils:is_acirclic/1 返回 false 后查找循环或循环

    我怎样才能 有效地 在Erlang有向图中找到循环或循环digraph utils is acyclic 1返回假 EDIT is acyclic is 定义为 https github com erlang otp blob maint
  • Erlang 中的接受器池和负载平衡?

    From http www erlang org doc man gen tcp html accept 1 http www erlang org doc man gen tcp html accept 1 值得注意的是 accept 调
  • 如何确定ETS表的确切内存大小?

    给定一个包含数据的 ETS 表 info 1 函数返回该表的各种属性 包括size该值特定于行数而不是物理大小 有没有办法计算 ETS 表占用的内存量 以字节为单位 ets new mytable bag named table compr
  • 如何在 Erlang 中将整数列表连接到字符串?

    我有这个元组 如下所示 127 0 0 1 现在我想将该元组作为字符串传递 127 0 0 1 到外部库 地理 IP 库 将此元组转换为字符串的最佳方法是什么 您可以随时使用inet parse ntoa 1 1 gt inet parse
  • 为什么 epmd 进程不退出?

    在我退出 erlang shell 后 epmd 进程仍然存在 这是一个错误还是一个功能 这是很正常的 EPMD 是一个主机守护进程 当人们打算使用分布式节点时 就需要它的存在 当仅在同一台机器上使用多个节点时 它也很有用
  • Erlang 中的函数链

    最好创建像 Active Record 或 Hibernate 这样的 ORM 它应该像这样处理链式查询 User User new for login stackoverflow admin for password 1984 load
  • 强制变量声明的协议 - Objective C

    是否可以在 protocol中声明变量 只是为了强制程序员在实现类 实现此协议的类 标头和实现中添加这些变量 Thanks 简短回答 不 不可能那样做 您最多可以强制方法和属性的可用性
  • gen_server中的数据在supervisor重启后还会保留吗?

    我有一个启动许多 gen server 的主管 每个 gen server 都有大量的数据加载 这需要花费大量的时间 我想知道当错误发生时 存储在 gen server 状态及其进程字典中的数据是否会保留以供下次启动 这样我就不需要再次初始
  • Erlang 进程如何(如果有的话)映射到内核线程?

    Erlang 因能够支持许多轻量级进程而闻名 它之所以能做到这一点 是因为它们不是传统意义上的进程 甚至不是 P 线程中的线程 而是完全在用户空间中的线程 这很好 实际上很棒 那么 Erlang 线程如何在多核 多处理器环境中并行执行呢 当
  • Erlang:有“epmd”的 API 吗?

    有没有办法查询 epmd 守护进程管理的名称表 The nodes 函数在这方面不是很有帮助 注意 我正在寻找 APIaside解析通过 stdout 生成的输出 要查询 epmd 可见的节点 请调用 EpmdModule net kern
  • 修复:客户端要求 GapFill,但我想发送 SequenceReset。应该有什么顺序?

    所以我的客户请求间隙填充 因为我们的序列已关闭 我不想重播消息 而是想发送 SequenceReset 我的问题很简单 我要发送给他的这个SequenceReset的消息序列应该是什么 我不希望我的客户端放弃它 因为它无法识别我的 Sequ
  • Swift:覆盖子类内的类型别名

    所以我正在考虑在我的项目中使用自定义模式 但我无法让它发挥作用 主要思想是改变typealias在每个子类上访问子类特定的接口 protocol InstanceInterface class typealias Interface var
  • 返回 Self 的协议函数

    我有一个返回对象副本的协议 P protocol P func copy gt Self 和一个实现 P 的 C 类 class C P func copy gt Self return C 但是 我是否将返回值设置为Self我收到以下错误
  • Erlang dict的时间复杂度

    我想知道 Erlang OTP 是否dict模块是作为哈希表实现的 在这种情况下它是否能提供这样的性能 平均情况 Search O 1 n k Insert O 1 Delete O 1 n k 最坏的情况下 Search O n Inse

随机推荐

  • 如何在 Swift 中制作引脚注释标注?

    我试图让标注工作 但没有发生 因为我在准备继续时做错了 我想知道如何能够对另一个视图进行引脚注释标注 当点击标注中的按钮时 跳转到另一个场景的过程如下 Set the delegate地图视图作为视图控制器 您可以在 Interface B
  • 包含所有私有成员的类可以是 POD 类吗?

    我之前听说过 POD 类型不能有私有数据 但根据 C 0x 草案 我的要求更宽松 强调我的 has the 相同的访问控制 第 11 条 对于所有非静态数据成员 这似乎表明私有数据只要是私有的就可以 我没有 C 03 的副本来检查 那么 W
  • 在完整框架 4.7 项目上添加对 .NET Core 2.0 DLL 的引用

    我在这里寻找这个问题但没有找到答案 我有一个针对 NET Core 2 0 的类库项目和一个针对 NET Full Framework 4 7 的 WPF 项目 我无法引用 WPF 项目上的类库 我收到以下错误 项目 xxxxxxxx 的目
  • 如何使用 IIS7 修复 CSS 文件内链接的 URL 重写

    我正在尝试为家里的朋友设置代理服务器 我目前正在关注网站上的教程 http blogs iis net carlosag archive 2010 04 01 setting up a reverse proxy using iis url
  • 将 NSTimer 的触发时间重置为从现在开始而不是上次触发

    我有一个NSTimer以 3 秒的间隔触发以减少值 当我执行增加该值的操作时 我想重新启动计时器 从该点开始计时 3 秒 例如 如果我增加该值并且计时器将在 1 秒内触发 我想更改它并让计时器在 3 秒内触发 我可以使计时器无效并重新创建它
  • 从Python中独立于操作系统的位置加载配置文件

    在Linux下我把我的配置放在 programname 中 我应该将其放置在 Windows 中的什么位置 在 python 中打开独立于操作系统的配置文件的推荐方法是什么 谢谢 内森 在 Windows 上 您将其存储在os enviro
  • 如何制作一个通过其他两个枚举器进行延迟迭代的 ruby​​ 枚举器?

    假设我有两个枚举器 enum1 and enum2必须延迟迭代 因为它们有副作用 如何构造第三个枚举器enum3 where enum3 each x x would lazily返回相当于enum1 enum2 在我的现实用例中 我正在流
  • 正确使用JTidy净化HTML

    我正在尝试使用 JTidy jtidy r938 jar 来清理输入 HTML 字符串 但我似乎无法正确设置默认设置 通常 诸如 hello world 之类的字符串在整理后最终会变成 helloworld 我想展示我在这里所做的事情 任何
  • 缓存一致性协议如何强制原子性?

    我知道原子性可以在诸如xsub 不使用LOCK前缀 依靠缓存一致性协议 MESI MESIF 1 缓存一致性协议如何做到这一点 这让我想知道缓存一致性协议是否可以强制原子性 为什么我们需要特殊的原子类型 指令等 2 如果MOSI实现跨多核系
  • Ruby on Rails+PostgreSQL:自定义序列的使用

    假设我有一个模型叫Transaction其中有一个 transaction code属性 我希望该属性自动填充一个序列号 该序列号可能不同于id 例如 与id 1可以有transaction code 1000 我尝试在 postgres
  • 是否有一个不使用回调的 $getJSON 版本?

    我正在为 3rdParty javascript 库实现回调 我需要返回该值 但我需要从服务器获取该值 我需要做这样的事情 3rdPartyObject getCustomValue function return getJSON myUr
  • 表视图控制器每一行连接到不同的视图控制器

    我正在尝试开发一个表视图控制器 其中行连接到多个View Controllers 文本字段 文本视图 表格视图 日期选择器 图像视图等 因此 如果我单击任何行 它应该打开Intermediate View并将适当的控制器放置在一个公共位置
  • Common Lisp 中对象的内存使用情况

    有没有办法找出类或基本数据类型的实例一般使用了多少内存 我在 cl 中有一个玩具网络框架 它使用代表 html 标签及其属性的类实例创建和管理网页 并且由于它们应该创建一个 html 页面 因此它们在称为 children 的插槽中拥有子级
  • 寻找一种方法来动态添加更多列表到 jQuery Mobile 列表视图的底部

    我正在寻找一种在向下滚动后将更多列表添加到列表视图底部的方法 例如 我最初退货了 20 件商品 我打算使用分页 只返回从查询中返回的尽可能多的内容 但我宁愿返回 15 20 然后在滚动结束时自动向此列表添加更多内容 或者有一个按钮显示 查看
  • Angular 2 rc3 路由器弃用包问题

    欢迎 Angular 2 rc 3 I use project json from 5 分钟快速入门配置我的项目 但是当我运行时npm install我收到以下错误 No compatible version found angular e
  • C++20 范围适配器的递归应用导致编译时无限循环

    C 20 中的范围库支持表达式 auto view r std views drop n 删除第一个n范围的元素r与范围适配器drop 但是 如果我递归地从范围中删除元素 编译器将进入无限循环 最小工作示例 在 GCC 10 中编译需要无限
  • TYPO3 - 调用另一个存储库

    是否可以在不同的控制器中调用一个函数 我需要打电话FindByCategoryGrouped catId 在 designRepository php 和getCategories catId 来自categoryRepository ph
  • Terraform:从命令行提供列表输入值?

    有没有办法从命令行提供列表值 地图有变量合并 但它似乎不适用于列表 我希望有类似的东西 但没有运气 谢谢 terraform apply var listvar abc1 var listvar abc2 或者可能 terraform ap
  • Django - 使用从类似 REST 的 API 检索的数据构建报告的应用程序

    我一直在构建一个 Django 应用程序 它使用来自扩展的类似 REST 的 API 的数据 API 是使用 NET 构建的 哎呀 不是我的选择 因为我宁愿挖出我的眼球也不愿学习 Microsoft 工具 我是一个 nix OSX 人 而且
  • 如何设计灵活的Erlang协议栈创建API

    我对当前的方法不满意 只是尝试重新设计在 Erlang 中构建协议栈的方式 该功能按重要性排序 表现 添加新协议变体的灵活性和实施速度 它将有助于开发从 shell 探索协议变体 我当前的型号 这个问题已经描述过除了通过函数调用发送 和通过