2019年2月11日

erlang 如何支援多個設定檔

通常 erlang project 會將設定的資料放在 sys.config 裡面,同樣的,很多 library 也會在說明文件裡面提到,要將該 library 相關的設定資訊,寫在 sys.config 裡面,在規模稍大的 project 就會看到一個很冗長複雜的設定檔。

但其實在 elang config 的標準文件 sys.config 說明裡面有提到,sys.config 裡面的語法是

[{Application, [{Par, Val}]} | File].

File 的部分就是附加的設定檔,erlang 會將所有設定檔裡面,對於某個 application 相關的所有參數,依照檔案順序整合在一起

首先利用 rebar 產生一個測試的 application myapp,並進行編譯

$ rebar create-app appid=myapp
==> erltest (create-app)
Writing src/myapp.app.src
Writing src/myapp_app.erl
Writing src/myapp_sup.erl

$ rebar compile
==> erltest (compile)
Compiled src/myapp_app.erl
Compiled src/myapp_sup.erl

然後依照以往的做法,將 myapp 的參數寫在 sys.config 裡面

[
    { myapp, [
        {par1,val1},
        {par2,val2}
    ]},
    { myapp, [
        {par1,newval1},
        {par3,newval3}
    ]}
].

注意,我們刻意將 myapp 的參數分成兩個部分撰寫,然後我們可以在 console 啟動 myapp,並利用 application:get_all_env(myapp). 取得 myapp 所有的參數進行測試。

$ erl -pa ebin -config sys
1> application:get_all_env(myapp).
[]
2> application:load(myapp).
ok
3> application:get_all_env(myapp).
[{par2,val2},
 {par1,newval1},
 {included_applications,[]},
 {par3,newval3}]

透過測試結果可以發現 myapp 的三個參數,是依照參數定義的順序累加並覆蓋得到的。


接下來,我們建立一個新的設定檔 conf/node1.config,內容為

[
    { myapp, [
        {par1,node1_val1},
        {par2,node1_val2},
        {parN,node1_valN}
    ]}
].

project 的目錄及檔案是這樣,也就是增加了一個 conf 的目錄

conf\
    node1.config
ebin\
src\
    myapp_app_erl
    myapp_sup.erl
    myapp_app.src
sys.config

然後修改 sys.config,把 node1.config 的設定附加在後面

[
    { myapp, [
        {par1,val1},
        {par2,val2}
    ]},
    { myapp, [
        {par1,newval1},
        {par3,newval3}
    ]}
    , "conf/node1.config"
].

這時候測試得到的結果會發現,node1.config 的設定覆蓋了原本 sys.config 裡面的設定

$ erl -pa ebin -config sys
1> application:get_all_env(myapp).
[]
2> application:load(myapp).
ok
3> application:get_all_env(myapp).
[{par2,node1_val2},
 {par1,node1_val1},
 {included_applications,[]},
 {par3,val3},
 {parN,node1_valN}]

我們可以將 sys.config 的機制,運用在兩個地方

  1. 分離 library 的設定檔 將某些 library 的設定,以獨立的設定檔方式撰寫
  2. 覆寫獨立的 node 的設定檔 將新的 node 的設定檔,也就是每一個 node 不同的設定資料,不修改既有的 sys.config 而是寫在 node 的設定檔,覆寫既有的設定

不過如果檔案的部分可以支援這樣的寫法 "conf/*.config",對於 library 設定檔的整合,會比較簡單。但如果支援了 *.config,就無法自定設定檔的引用順序,可能只能依照字母的順序排序了。

References

A little known fact about Erlang's sys.config

An easy way to handle configuration parameters in Erlang

節點啟動後自動連接其它配置節點

[erlang-questions] Multiple application configurations in multiple files

沒有留言:

張貼留言