繁体   English   中英

该Erlang sys.config如何分解?

[英]How can this Erlang sys.config be decomposed?

给定一个如下所示的Erlang sys.config

[
    {mousetrap, [
        {slack_user, "mousetrap"},
        {slack_channel, "#mousetrap"},
        {slack_token, "<slack token here>"},
        {pins_export_file, "/sys/class/gpio/export"},
        {pins_root_directory, "/sys/class/gpio/gpio"},
        {pins, [
                {gpio0, 30, "1 (over workshop door)"},
                {gpio0, 31, "2 (by basement freezer)"},
                {gpio1, 16, "3 (in the kitchen pantry)"},
                {gpio0, 5, "4 (Not yet wired)"}
        ]},
        {quiet_minutes, 5},
        {pin_check_interval_seconds, 1}
    ]}
].

我想对其进行分解,以便将每个组件的设置都放在配置文件中。 例如,BeagleBone的pin_library实际上没有理由包括整个捕鼠器应用程序的知识,因此有必要对其进行介绍。 同样,对于将消息发送到Slack的notification_library:

[
    {mousetrap, [
        {pins, [
                {gpio0, 30, "1 (over workshop door)"},
                {gpio0, 31, "2 (by basement freezer)"},
                {gpio1, 16, "3 (in the kitchen pantry)"},
                {gpio0, 5, "4 (Not yet wired)"}
        ]},
        {quiet_minutes, 5}
    ]},
    {pin_server, [
        {pins_export_file, "/sys/class/gpio/export"},
        {pins_root_directory, "/sys/class/gpio/gpio"},
        {pin_check_interval_seconds, 1}
    ]},
    {notification_library, [
        {slack_user, "mousetrap"},
        {slack_channel, "#mousetrap"},
        {slack_token, "<slack token here>"}
    ]}
].

但是,这不起作用,因为pin_server和Notification_library都不是应用程序,这是sys.config中此构造所要求的。 将这些设置分为适当的类别的一种正确的Erlang方法是什么,以便可以使用以下方式更改pin_library.erl

{ok, PinsRootDirectory} = application:get_env(mousetrap, pins_root_directory),

使用

{ok, PinsRootDirectory} = application:get_env(pin_server, pins_root_directory),

编辑:

只是为了阐明为什么我认为这很重要。 组件pin_server和notification_library尝试遵守SRP 但是,当pin_server调用application:get_env(mousetrap, pins_root_directory) ,它打破了SRP的墙,因为它在不应该具有依赖项的组件上创建了依赖项。 也就是说,在捕鼠器应用程序上。 现在,如果不更改代码,便无法在其他应用程序中重用。 notification_library也是如此。 pin_server可能适用于任何要询问BBB引脚的应用程序。 notification_library在任何想要发送Slack通知的应用中都很有用。 两者都不应引用捕鼠器应用程序,因为它们不应对该应用程序有任何“了解”。

编辑:

根据@michael的指导,我首先将松弛通知分发到位于https://github.com/DonBranson/slack的单独的OTP库。

由于Erlang不会以任何方式控制节点内应用程序和环境之间的访问(任何应用程序都可以访问任何其他应用程序环境),因此我不确定这种微妙的用途变化会为您带来什么真正的好处……事实上,如果合乎逻辑的是pin_server显然是捕鼠器应用程序的一部分,那么我认为您不应该尝试这样做。 与应该使用的系统一起使用。

话虽如此,由于没有这样的访问控制,因此您可以为不存在的应用程序设置环境,如下所示:

application:set_env(nonexisting, foo, bar).
application:set_env(anotherphantom, bat, baz).

但是,如果您在sys.config中使用不存在的应用程序运行节点,则不会加载这些应用程序的配置。

你可以做的黑客

您可以在启动顶级管理程序之前,让您的应用程序开始阅读您的环境,并设置不存在的pin_server应用程序的环境,并从捕鼠器应用程序中取消设置环境。 这样可以实现您想要的,但是...

即使有可能,我也不推荐这样做,因为如果稍后引入您所使用的名字的应用程序,发布管理器显然不会发现冲突,这很可能会带来一些危险。

更好的选择(应用程序和包含的应用程序)

另一种方法是使pin_server成为应用程序。

如果这样做的唯一障碍是,除非在捕鼠器应用程序的上下文中,建议的pin_server应用程序根本没有任何意义,那么您可以将其设置为“包含的应用程序”。 包含的应用程序是具有自己的应用程序文件的应用程序,实际上与普通(主)应用程序一样,但是它们在您的主应用程序的监视树中启动(请参阅Included Applications ),并且将立即允许您更改使用方式如果您不介意创建额外的应用程序,则可以。

图书馆申请

同样,它是一个应用程序,我认为这可能不适合您的情况,但是,还有一个“库应用程序”之类的东西,它是没有服务器的应用程序(您无需实现该应用程序回调模块,它只是对您的模块,API和环境的逻辑分组)。 如果创建不带mod条目的应用程序文件,它将成为库应用程序。 我认为不合适的原因是pin_server听起来像服务器,因此应受到监督,但这也将允许您更改所需的用途。

我认为最好的解决方案是要求所有使用pin_servernotification_library应用程序读取环境变量,并将它们在初始化时注入这些组件中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM