【问题标题】:How can this Erlang sys.config be decomposed?这个 Erlang sys.config 怎么分解?
【发布时间】:2015-11-07 03:03:28
【问题描述】:

给定一个看起来像这样的 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 beagleboneblack beagleboard slack


    【解决方案1】:

    由于 Erlang 不以任何方式控制节点内应用程序和环境之间的访问(任何应用程序都可以访问任何其他应用程序环境),我不确定您从这种微妙的使用变化中真正获得了什么......和事实上,如果 pin_server 显然是捕鼠器应用程序的一部分是合乎逻辑的,我认为你不应该尝试这样做;使用系统,因为它应该被使用。

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

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

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

    你可以做的黑客攻击

    在启动顶级主管之前,您可以让您的应用程序开始读取您的环境并设置不存在的 pin_server 应用程序的环境,并从 mousetrap 应用程序中取消设置环境。这会达到你想要的,但是......

    即使有可能,我也不建议这样做,因为如果稍后引入您盗用的名称的应用程序,发布管理器显然不会发现冲突。

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

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

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

    库应用程序

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

    【讨论】:

      【解决方案2】:

      我看到的最佳解决方案是要求任何使用 pin_servernotification_library 的应用程序在初始化时读取环境变量并将它们注入到这些组件中。

      【讨论】:

      • 在我看来,您在提倡我在回答中标记为 hack 的内容。我真的只是为了完整性而列出了这个选项,因为它直接允许你在不改变结构的情况下完成你想要的......但是考虑到你对 SRP 合规性的额外编辑,我比以往任何时候都更想说正确的答案是拥有 pin_server 和notification_library 作为单独的(主要)应用程序。你已经澄清了它们是有用的独立的,所以如果你让它们成为他们自己的应用程序,任何 Erlang 开发人员都会期望并理解它,然后你就可以编写你的 sys.config 而不会有任何混乱。
      • 它们不能单独使用。它们仅在与应用程序结合使用时才有用。
      • 另外,我的建议与您的建议不同,因为我会注入设置而不是设置另一个环境变量。
      • 好点。例如,像 inets 一样,作为 Erlang 应用程序,在独立应用程序中很有用。
      • 是的,或者 stdlib、kernel、public_key、c​​ompiler... 可能只有一小部分 Erang 应用程序是那些收集在一起并使用其他应用程序并实际构成通常被视为应用程序的应用程序人们。如果The pin_server is potentially applicable to any application 那么我实际上会说在 Erlang 应用程序/节点/发布范式下,我会说它必须是 Erlang 应用程序或 Erlang 应用程序的一部分,以及您喜欢的任何其他内容,只要添加不会破坏您的 SRP 合规性。
      猜你喜欢
      • 1970-01-01
      • 2022-06-15
      • 2016-02-11
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      • 2018-02-25
      相关资源
      最近更新 更多