2016-05-03 6 views
1

私は単一の依存関係を持つ小さなテンプレートプロジェクトを持っています。私が求めているのは、アプリケーションが停止しても停止しても、その依存関係も停止され、ノードがシャットダウンされるということです。テンプレートプロジェクトでは、exampleという基本アプリケーションとdependという従属アプリケーションがあります。それぞれには、アプリケーション(suffixed _app)、プライマリスーパーバイザ(suffixed _sup)、および基本gen_server(suffixed _srv)の3つのモジュールがあります。 dependは、の{applicationsに登録されています。 Erlangのドキュメントによると Erlangアプリケーションは永続性で起動し、シャットダウン時にノードや依存関係を取りません。

  • 永久アプリケーションが終了した場合、他のすべてのアプリケーションとランタイムシステムも終了されます。

いいね。それはまさに私が欲しいものです。私はアプリケーションを起動します:

application:ensure_all_started(example, permanent). 

これで十分です。それでは、私は停止呼ん

1> application:ensure_all_started(example, permanent). 
<0.41.0>: depend_app:start(normal, []) 
<0.41.0>: depend_sup:start_link() 
<0.42.0>: depend_sup:init([]) 
<0.42.0>: depend_srv:start_link() 
<0.43.0>: depend_srv:init([]) 
<0.46.0>: example_app:start(normal, []) 
<0.46.0>: example_sup:start_link() 
<0.47.0>: example_sup:init([]) 
<0.47.0>: example_srv:start_link() 
<0.48.0>: example_srv:init([]) 

depend

1> application:stop(example). 
<0.46.0>: example_app:prep_stop([]) 
<0.48.0>: example_srv:terminate(shutdown, []) 
<0.46.0>: example_app:stop([]) 
ok 
2> 
=INFO REPORT==== 3-May-2016::08:22:41 === 
    application: example 
    exited: stopped 
    type: permanent 
2> 
がシャットダウンされていない、そしてそれだけでシェルでそこに座っている私は、各コールバックがコンソールにそのPID、関数名と引数を記録してい。私は、例えば、 erlang:exit/2でアプリケーションを殺す強制した場合、私は(脇クラッシュダンプからの)目的の動作を取得:

3> erlang:exit(pid(0,46,0), kill). 
true 
<0.41.0>: depend_app:prep_stop([]) 
<0.43.0>: depend_srv:terminate(shutdown, []) 
<0.41.0>: depend_app:stop([]) 
4> 
=INFO REPORT==== 3-May-2016::09:02:04 === 
    application: example 
    exited: killed 
    type: permanent 
4> {"Kernel pid terminated",application_controller,"{application_terminated,example,killed}"} 

Crash dump was written to: erl_crash.dump 
Kernel pid terminated (application_controller) ({application_terminated,example,killed}) 

D:\dev\app_test> 

しかし、なぜ正常にシャットダウンしませんか? permanentがドキュメントに書かれている内容に基づいているとは思わないので、transientまたはtemporaryアプリケーションとして動作しているようです。

追加のメモが1つありますが、私はバージョンがerts-5.10.4/otp-R16B03-1にロックされています。あなたが引用した同じドキュメントの下

答えて

3

だけビットが書かれている:

アプリケーションは常に application:stop/1を呼び出すことによって明示的に停止することができます。モードに関係なく、 の他のアプリケーションは影響を受けません。

あなたはアプリケーションが異常終了した場合にのみ動作することが正しいです。殺されたthis codeを参照してください - アプリケーションを停止するときにOTPが最初に行うことは、プロセスのリンクを解除し、アプリケーションが実行している情報を削除することです。 process terminated normallyは他のプロセスが受信できるシグナルを生成しないため、依存するアプリケーションを停止する必要があるかどうかの検出は、application_controllerと実行中のアプリケーションの間のリンクによって決まります。

+0

男の子、それは面白いです。ヘッドアップをありがとう。私はドキュメントを読んでいる間にその接続をしなかった。 OTPアプリケーションとその依存関係を分解する方法がありますか?私は過去にapplication_controllerデッドロックの問題に遭遇しましたが、今はアプリケーションのようです:stop/1は行く方法ではありません。 –

+0

私はあなたが何を意味するのか分からない。通常、アプリケーションはVMが動作している間は実行されています。明示的にアプリケーションをロード/開始/停止/アンロードする必要がある場合は、アプリケーションの 'start'と' stop'関数でそれを行うことができます:https://github.com/amiramix/humbundee/blob/master/lib /humbundee/src/hbd_app.erl#L30また、 'some_app'がロードされると' application:get_all_key(some_app).'を使って '.app'ファイルから依存するアプリケーションのリストを含むすべての詳細を得ることができます。 – Amiramix

関連する問題