簡體   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