erlang app 文件

http://hje.iteye.com/blog/1211734html

應用的概念¶ 
當咱們寫了實現特定功能的代碼以後,咱們可能想將代碼轉成一個 應用 (application),這是能夠做爲一個單元啓動和中止的組建,同時它也能夠在其餘系統中被重用。 

咱們要建立一個 應用回調模塊 ,其中描述了該應用應該如何被啓動和中止。 

而後,須要一個應用規格,它被放在一個 應用資源文件 。咱們還指定該應用由哪些模塊組成,以及各個回掉模塊的名字。 

若是咱們使用 systools ——Erlang/OTP用於打包的代碼(參見 發佈 ),每一個應用的代碼均可以按照預約的 目錄結構 放在單獨的目錄中。 

應用回調模塊¶ 
如何啓動和中止應用的代碼,即監督樹,由如下兩個回掉函數來描述: 

start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State} 
stop(State) 
當要經過啓動頂層督程來建立監督樹的時候,會調用 start 。它要返回頂層督程的pid和一個選項值 State ,默認爲 []。這個值會原樣傳遞給 stop 。 

StartType 一般是原子 normal 。只有在接管或故障轉移中才會有其餘值,參見 分佈式應用 。 StartArgs 由 應用資源文件 中的鍵 mod 來定義。 

在應用被中止以後會調用 stop/1 來進行必須的清除工做。注意應用實際的中止過程,也就是監督樹的關閉,是按照 啓動和中止應用 中所描述的方式自動處理的。 

如下是一個例子,未來自 督程 一章中的督程打包爲一個應用回調模塊: 

-module(ch_app). 
-behaviour(application). 

-export([start/2, stop/1]). 

start(_Type, _Args) -> 
    ch_sup:start_link(). 

stop(_State) -> 
    ok. 
一個庫應用——不能被啓動或者中止——則無須任何應用回調模塊。 

應用資源文件¶ 
咱們經過建立一個放在應用資源文件——簡稱 .app 文件——中的應用規格來定義一個應用: 

{application, Application, [Opt1,...,OptN]}. 
Application 是一個表明應用的名稱的原子。文件必須被命名成 Application.app 。 

每個 Opt 都是一個定義了應用某種特性的元組 {Key, Value} 。全部的鍵都是可選。忽略的鍵會使用默認的值。 

例如,用於庫應用 libapp 的最小化的 .app 文件的內容爲: 

{application, libapp, []}. 
對於像 ch_app 這樣的監督樹應用的最小化 .app 文件的內容爲: 

{application, ch_app, 
[{mod, {ch_app,[]}}]}. 
鍵 mod 定義了回調模塊以及應用的啓動參數,在這個例子中相應是 ch_app 和 []。這表示應用啓動的時候會調用: 

ch_app:start(normal, []) 
而當應用被中止的時候會調用: 

ch_app:stop([]) 
當使用 systools 時,Erlang/OTP工具的打包代碼(參見 發佈 ),鍵 description、vsn、modules、registered 和 applications 則應該指定爲: 

{application, ch_app, 
[{description, "Channel allocator"}, 
  {vsn, "1"}, 
  {modules, [ch_app, ch_sup, ch3]}, 
  {registered, [ch3]}, 
  {applications, [kernel, stdlib, sasl]}, 
  {mod, {ch_app,[]}} 
]}. 
description 
簡短描述,字符串。默認爲 「」。 
vsn 
版本號,字符串。默認爲」「。 
modules 
由該應用引入的全部模塊。當生成啓動腳本和tar文件時, systools 將用到這個列表。一個模塊必須被定義於且僅於一個應用。默認爲[]。 
registered 
應用中全部註冊進程的名稱。 systools 使用這個列表來探測在應用之間是否有名稱衝突。默認爲 []。 
applications 
全部在此應用以前必須啓動的應用。 systools 使用該列表來生成正確的啓動腳本。默認爲 [],可是注意任何應用都要至少依賴於 kernel 和 stdlib 。 
應用資源文件的語法和內容在 app(4) 中有詳細的描述。 

目錄結構¶ 
當使用 systools 對代碼進行打包的時候,每一個應用的代碼都放在單獨的目錄中 lib/Application-Vsn ,其中 Vsn 是版本號。 

即使沒有用到 systools ,最好也要了解它,由於Erlang/OTP其自身是按照OTP原則進行打包的因此纔有了這個目錄結構。若是存在一個應用的多個版本,那麼代碼服務器(見 code(3) )會自動使用來自目錄中版本號最高的代碼。 

應用目錄結構固然也能夠用於開發環境。版本號是能夠忽略的。 

應用目錄有如下子目錄: 

•src 
•ebin 
•priv 
•include 
src 
包含Erlang源代碼 
ebin 
包含Erlang目標代碼—— beam 文件。 .app 文件也放在這裏。 
priv 
用於應用專屬文件。例如,C執行程序就放在這裏。應該使用函數 code:priv_dir/1 來訪問這個目錄。 
include 
用於包含文件。 
應用控制器¶ 
當啓動了Erlang運行時系統,做爲Kernel應用的一些進程會被啓動。其中一個進程是應用控制器進程,註冊爲 application_controller 。 

全部對應用的操做都由應用控制器來協調。它經過模塊 application 裏的函數來暴露接口, 請參考 application(3) 。尤爲要了解,應用能夠被加載、卸載、啓動和中止。 

加載和卸載應用¶ 
在能啓動一個應用以前,首先它必須被加載。應用控制器會讀取在 .app 中的信息並存起來。 

1> application:load(ch_app). 
ok 
2> application:loaded_applications(). 
[{kernel,"ERTS  CXC 138 10","2.8.1.3"}, 
{stdlib,"ERTS  CXC 138 10","1.11.4.3"}, 
{ch_app,"Channel allocator","1"}]被中止的或者從未啓動過的應用,能夠被卸載。該應用相關的信息會從應用控制器的內部數據庫中刪除。 

3> application:unload(ch_app). 
ok 
4> application:loaded_applications(). 
[{kernel,"ERTS  CXC 138 10","2.8.1.3"}, 
{stdlib,"ERTS  CXC 138 10","1.11.4.3"}]Note: 
加載/卸載應用並不會加載/卸載該應用所使用的代碼。代碼加載是按照通常的方式進行的。 

啓動和中止應用¶ 
啓動應用要調用: 

5> application:start(ch_app). 
ok 
6> application:which_applications(). 
[{kernel,"ERTS  CXC 138 10","2.8.1.3"}, 
{stdlib,"ERTS  CXC 138 10","1.11.4.3"}, 
{ch_app,"Channel allocator","1"}]若是應用還沒有被加載,那麼應用控制器會首先使用 application:load/1 加載它。它會檢查 applications 鍵對應的值,來確保要在該應用運行以前啓動的應用都啓動了。 

而後應用控制器爲應用建立一個應用主程序。它是該應用中全部進程的隊長。應用主程序經過調用應用模塊中的回調函數 start/2 啓動應用(會給出由在 .app 文件中的 mod 建定義的啓動參數)。 

中止一個應用,但不卸載,可調用: 

7> application:stop(ch_app). 
ok 
配置應用¶ 
可使用配置參數來對應用進行配置。它們在 .app 文件中是一個由鍵 env 指定的 {Par, Val} 元組列表。 

{application, ch_app, 
[{description, "Channel allocator"}, 
  {vsn, "1"}, 
  {modules, [ch_app, ch_sup, ch3]}, 
  {registered, [ch3]}, 
  {applications, [kernel, stdlib, sasl]}, 
  {mod, {ch_app,[]}}, 
  {env, [{file, "/usr/local/log"}]} 
]}. 
Par 必須是一個原子, Val 能夠是任意值。應用能夠經過調用 application:get_env(App, Par) 或一些其餘相似函數來獲取配置參數的值,參見 application(3) 。 

例如: 

% erl 
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0] 

Eshell V5.2.3.6  (abort with ^G) 
1> application:start(ch_app). 
ok 
2> application:get_env(ch_app, file). 
{ok,"/usr/local/log"}.app 文件中的值能夠被系統配置文件中的值所覆蓋。系統配置文件是一個包含相關應用的配置參數的文件。 

[{Application1, [{Par11,Val11},...]}, 
..., 
{ApplicationN, [{ParN1,ValN1},...]}]. 
系統配置要被命名爲 Name.config 而且要使用命令行參數 -config Name 來啓動Erlang。更多信息參見 config(4) 。 

例如:建立一個文件 test.config 包含一下內容: 

[{ch_app, [{file, "testlog"}]}]. 
file 的值將覆蓋在 .app 文件中所定義的 file 的值: 

% erl -config test 
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0] 

Eshell V5.2.3.6  (abort with ^G) 
1> application:start(ch_app). 
ok 
2> application:get_env(ch_app, file). 
{ok,"testlog"}若是使用了 發佈處理 ,那麼只能使用一個系統配置文件同時該文件必須叫作 sys.config 。 

在 .app 文件中的值,也包括系統配置文件中的值,均可以直接在命令行中被覆蓋: 

% erl -ApplName Par1 Val1 ... ParN ValN例如: 

% erl -ch_app file '"testlog"' 
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0] 

Eshell V5.2.3.6  (abort with ^G) 
1> application:start(ch_app). 
ok 
2> application:get_env(ch_app, file). 
{ok,"testlog"}應用啓動類型¶ 
當啓動應用的時候要定義一個啓動類型。 

application:start(Application, Type) 
application:start(Application) 和調用 application:start(Application, temporary) 是同樣的。類型還能夠是 permanent 持久的或者 transient 過渡的: 

•若是一個持久應用終止了,全部其餘的應用以及運行時系統都會被終止。 
•若是一個過渡應用以 normal 理由終止了,那麼這個信息會被上報可是不會終止其餘應用。若是一個過渡應用異常終止了——即以非 normal 的理由終止了——那麼其餘應用以及運行時環境也會被終止。 
•若是一個臨時(temporary)應用終止了,那麼會報告該信息但不會終止其餘應用。 
咱們老是能夠經過明確調用 application:stop/1 來中止一個應用。不管是什麼模式,都不會影響其餘應用。 

注意在實踐中不多使用過渡模式,由於當一個監督樹終止了,退出理由會被設置爲 shutdown ,而非 normal 。 


http://erlang.shiningray.cn/otp-design-principles/applications.htmlshell

相關文章
相關標籤/搜索