この章は、app(4)とapplication(3)と合わせて読んでください。
いくつかの機能を実装するコードを書いたら、それを単位ごとに起動停止ができ、他のシステムでもうまく再利用できるように、 アプリケーション としてにまとめたいと思うでしょう。
これを行うためには、アプリケーションの起動と停止に関するコードを記述した、 アプリケーション・コールバックモジュール を作成します。
また、 アプリケーション・リソースファイル に書かれた、 アプリケーションの仕様 が必要となります。これ以外には、アプリケーションがどのモジュールから構成されるのか、コールバックのモジュール名を調べます。
もしsystools、Erlang/OTPのコードのパッケージツールを使用するのであれば、コードは、これから説明する事前に定義された ディレクトリ構造 に、アプリケーションごとにコードを配置します。
監視ツリーなど、アプリケーションの開始と終了でどのようなことをするかは、次の2つのコールバック関数で定義します。
start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State}
stop(State)
start 関数はアプリケーションの起動時に呼び出されます。この関数内では、トップレベルのスーパバイザを起動し、監視ツリーを作る必要があります。この関数はトップのスーパバイザと、追加の項の State を返すことが期待されます。デフォルトの State は [] です。この項はそのまま stop 関数に渡されます。
StartType は通常アトムが使用されます。もし、テイクオーバー、あるいはフェイルオーバーの時は別の値を受け取ります。これらに関しては分散アプリケーションの説明を参照してください。 StartArgs は アプリケーション・リソースファイル の中の、 mod キーで定義されています。
stop/1 はアプリケーションの停止後に呼ばれます。この中には、必要な終了処理を実装しなければなりません。実際のアプリケーションの終了では、監視ツリーのシャットダウンは starting_and_stopping_application の中で説明します。
サンプルとして、 スーパバイザ・ビヘイビア の章の監視ツリーをパッケージ化するアプリケーションコールバックモジュールのサンプルを紹介します。
-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} というタプルで、アプリケーションのプロパティを定義します。すべてのキーはおプヨンです。省略したキーにタイしては、デフォルトの値が使用されます。
最小の、ライブラリアプリケーション向けの .app ファイルのサンプルは次の通りです。
{application, libapp, []}.
監視ツリーのための最小の .app ファイルのサンプルの ch_app.app は、次のようになります。
{application, ch_app,
[{mod, {ch_app,[]}}]}.
mod キーは、コールバックモジュールと、アプリケーションのスタート時の引数を定義します。この場合は、 ch_app モジュールに引数 [] を渡すという指定になっています。これは、
ch_app:start(normal, [])
という呼び出しがアプリケーションの起動時に行われ、
will be called when the application should be started and
ch_app:stop([])
という処理がアプリケーションの終了時に呼ばれます。
systools を使用している場合、コードをパッケージ化するErlang/OTPのツール( リリース 参照)を使用する場合は、 description, vsn, modules, registered, aapplication というキーを定義する必要があります。
{application, ch_app,
[{description, "Channel allocator"},
{vsn, "1"},
{modules, [ch_app, ch_sup, ch3]},
{registered, [ch3]},
{applications, [kernel, stdlib, sasl]},
{mod, {ch_app,[]}}
]}.
modules
このアプリケーションに含まれる全モジュールです。 systools は、ブートスクリプトの生成や、tarファイルの作成にこのリストを使用します。モジュールは1つのアプリケーションにつき、1つ定義されなければなりません。デフォルトは [] です。
registered
プリケーション内で、登録されたプロセスのすべての名前を指定します。 systools はこのリストを用いて、アプリケーション間の名前の衝突を検知します。デフォルトは [] です。
applications
このアプリケーションの起動前に起動しておかないといけない全アプリケーションを指定します。 systools は、正しいブートスクリプトを起動するのに、このリストを利用します。デフォルトは [] ですが、すべてのアプリケーションは最低でも kernel `` と ``stdlib に依存しています。
アプリケーションリソースファイルの文法と内容については、app(4)の中で詳細に説明します。
systools を用いてコードをパッケージングするときは、それぞれのアプリケーションのコードは lib/Application-Vsn という個別のディレクトリに分けて配置して置きます。 Vsn はバージョン番号です。
このやり方は、例え systools を使っていなかったとしても、Erlang/OTP自身がこの原則に従って、このディレクトリ構造でパッケージングされているため、知っておくと便利です。もし複数バージョンのアプリケーションがある場合、コードサーバ(code(3)参照)は自動的に、バージョン番号の高いものを選択します。
もちろん、アプリケーションのディレクトリ構造は開発環境の中で使用することもできます。また、バージョン番号は名前から取り除かれる場合があります。
アプリケーションディレクトリには次のようなサブディレクトリが含まれます。
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 を利用してロードします。この関数はアプリケーションキーの値をチェックし、そのアプリケーションの起動前に実行されているべき、すべてのアプリケーションが稼働されていることを確認します。
アプリケーション・コントローラは、そのアプリケーションのための アプリケーション・マスター を作成します。アプリケーションマスターは、そのアプリケーションのすべてのプロセスのグループのリーダーです。アプリケーションマスターは、アプリケーションのモジュールに定義されたコールバック関数の start/2 に、 .app ファイルの mod キーで定義された起動時の引数を付けて呼び出し、アプリケーションの実行を開始します。
アプリケーションをロードしたままの状態で停止させるには、次のように呼び出します。
7> application:stop(ch_app).
ok
アプリケーションマスターは、トップのスーパバイザに停止するように伝えて、アプリケーションを停止させます。トップのスーパバイザは、すべての子プロセスに停止するように伝え、ツリー全体は、起動した時とは逆の順序で終了します。全部の子プロセスが停止したら、アプリケーションマスターは、 mod キーで定義されたファイルのコールバック関数の stop/1 を呼び出します。
アプリケーションは設定パラメータを使用して、設定を行うことができます。これらは、 .app ファイル内の、 {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 で呼び出されるか、Erlangの起動引数として、コマンドライン引数の -config Name を使用して読み込ませます。詳しくはconfig(4)を参照してください。
例: test.config というファイルの中身が次のように書かれていたとします。
[{ch_app, [{file, "testlog"}]}].
file というキーの値が、まるで .app ファイルの中で元々そのように定義されてあったように、このファイルの値でオーバーライドされます。
% 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"}
もしも、 アプリケーション仕様のアップデート が使用されていて、1つのシステム構成だけが使用されるのであれば、そのファイルは 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 が設定できます。
application:stop/1 を呼び出して、アプリケーションを明示的に終了させることはいつでもできます。この場合は、モードに関わらず、他のアプリケーションは影響を受けません。
transient モードは、 normal 以外の理由を付けて監視ツリーを終了するような場合にはあまり使えない、ということに注意してください。
Copyright (c) 1991-2009 Ericsson AB