問題:
當我們把一個專案中所有的supervision tree通過一個簡單的函式game: start(),會發現這個樹結構特別複雜,只能有一個根節點,然後一直擴充套件。
那麼有時,我們會需要:有些功能模組不啟動,有些啟動,如果再去改這顆樹的結構,就會很麻煩。這裡,這就是application出現的原因,設計一個可以隨時開關的子塊(application).比如:上圖中的log app, db app ,game app, connect app ..
這樣對這些應用的開關管理就非常方便啦,【試想你如果用supervisor,執行時還要手動去停程式樹,然後還要移除監控樹,還要做clean工作,下次啟動還要做start工作…】,這些定義好application後,自然會把這個當成一個單元處理啦!這大概就是程式設計思想的體現吧。
如何構造一個典型的erlang application? 下面我們通過把[Erl_Question07] Erlang 做圖形化程式設計的嘗試:純Erlang做2048遊戲 的遊戲改為application啟動來做示範
原來的通過erl Script 啟動是可以的,變成application有什麼好處呢?
that can be started and stopped as a unit, and which can be re-used in other systems as well. 使用application方便隨時只啟動或關閉以application為單位的應用,其它application完全不受影響,這可以方便的管理一個大專案的各個功能,把這些功能都分成一個個小應用,又有層次又方便管理。
步驟:
1. 定義 .app檔案,格式如下
%% game2048.app {application, game2048, [ {description, "pure erlang game 2048 for fun"}, %%description應用說明,預設為"" {vsn, "1"}, %% 版本號 {modules, []},%%All modules introduced by this application,systools使用這個list來生成boot script and tar file tar,這個module必須只能被一個且只能是一個application定義過 {registerd,[]},%%All names of registered processes in the application. systools uses this list to detect name clashes between applications. Defaults to []. {applications, [ kernel, stdlib ]},%%All applications which must be started before this application is started. systools uses this list to generate correct boot scripts. Defaults to [], but note that all applications have dependencies to at least kernel and stdlib. {mod, {game2048_app, []}},%% call game2048_app:start(normal, []) ,game2048_app:stop([]) {env, []} ]}.
2.給遊戲加入監控程式:game2048_sup.erl
init([]) -> RestartStrategy = one_for_one, MaxRestarts = 1000, MaxSecondsBetweenRestarts = 3600, SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}, Restart = permanent, Shutdown = 2000, Type = worker, AChild = {'game2048', {'game2048', start, []}, %%監控的是game2048:start() Restart, Shutdown, Type, []}, {ok, {SupFlags, [AChild]}}.
3. 因原來的game2048: start()返回值改為{ok,PID}模式,這是supervisor規範要求的。
4. 重新編譯程式碼,改造application工作完成。
你可以通過以下方式啟動 application client.
1. 啟動一個erlang shell :
erl -name test -pa "app所在目錄" -pa "ebin目錄" >application:start(game2048).
>application: stop(game2048).
2.當然你可以把application和其它的application共同使用,【不久我會把lager application也用來這裡面來,大材小用學習下優秀程式碼也好:)】
變成application,好開心,居然看到和kernel並在一起,是不是高階點【使用observer:start().檢視:
Tip: 你使用 erl 啟動一個Shell時是不會啟動 net_kernel模組的,導致分散式出錯,如果加上 –name 指定節點名就會啟動啦。