将系统划分为OTP应用时,应该在哪里放置全局gen_server?

问题描述

TL; DR

如果OTP应用程序A调用了应用程序B中全局注册的gen_server,而我又不想将所有应用程序B安装在不运行它的节点上,那么该如何处理gen_servers客户端代码? >

背景(略有简化)

我有一个使用分布式erlang的系统,两个节点具有不同的用途,并且运行的代码大多不同。到目前为止,我一直在使用手工制作的Makefile,并在两个节点上都安装了所有软件。其中一些代码是与主管一起作为OTP应用程序运行的,但是并没有系统地完成,因此并非所有模块都在适当的监督树的一部分的任何应用文件中列出。

在每个节点上运行的代码的依赖性非常不同,我想将其划分为OTP应用程序(每个节点一个),以构建发行版并分别安装它们。我希望这可以让我放弃手工制作的Makefile文件并切换到rebar3。

一个节点在所有erlang中都运行一个中央服务器,它具有与另一节点无关的依赖项(cowboy)。另一个节点运行使用服务器的客户端程序,但也使用服务器节点不需要的不同端口程序和gui库。

问题

客户端与服务器交互的方式是通过对全局注册的gen_server的客户端API进行常规函数调用。即在服务器节点上运行的gen_server,在同一模块中具有其客户端功能。这意味着该gen_servers束文件需要同时存在于两个节点中,但应仅是其中一个应用程序中监督树的一部分。

此gen_server中的服务器端代码使用仅在服务器节点中需要的其他模块,因此gen_server的测试代码也依赖于这些其他模块。 (我知道可以通过在测试中进行适当的模拟来解决。)

我考虑了哪些解决方案?

将其放入图书馆应用程序中

我可以将gen_servers代码放在其他两个都依赖的库应用中。出于某些原因,这很奇怪。

  • gen_server模块不会与它依赖的其他模块属于同一应用程序(与代码中的实际依赖关系相比,应用程序级别的依赖关系将被颠倒)。
  • 测试代码要么需要保留在服务器应用程序中(与其所测试的代码不在同一个应用程序中),要么需要进行重新工作以不依赖周围的模块(这很好,但是很耗时)。

在两个版本中都包含服务器应用程序

我可以在两个节点中都包含服务器应用程序,并让主管代码检查它是否应该根据初始化参数或节点名称实际启动任何操作。但这会打败我要达到的目的。

在两个应用程序中都包含gen_server模块

我也可以使用符号链接或其他方式在客户端应用程序中包含gen_server模块。我想它可以用,但感觉很脏。

将gen_server模块分为客户端模块和服务器模块

然后可以将客户端模块放在客户端应用程序中(如果该服务器的某些部分也使用它,则可以放置在lib中)。它将与gen_severs的通常编写方式转移很多。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...