2016-05-03 1 views
1

Ich habe ein kleines Template-Projekt mit einer einzigen Abhängigkeit. Das Verhalten, das ich suche, ist, dass, wenn die Anwendung gestoppt wird, jedoch gestoppt wird, ihre Abhängigkeiten ebenfalls gestoppt werden und der Knoten heruntergefahren wird. Im Vorlagenprojekt habe ich eine Basisanwendung namens example und eine abhängige Anwendung namens depend. Jeder hat 3 Module: die Anwendung (suffixed _app), den primären Supervisor (suffixed _sup) und einen grundlegenden gen_server (suffixed _srv). depend ist im {applications Eintrag in example.app registriert.Erlang Anwendung gestartet mit permanenten nicht Knoten oder Abhängigkeiten beim Herunterfahren

die Erlang docs Laut:

  • Wenn eine permanente Anwendung, alle anderen Anwendungen, und das Laufzeitsystem beendet werden ebenfalls beendet.

Klingt gut. Genau das möchte ich. Ich starte die Anwendung mit:

application:ensure_all_started(example, permanent). 

Das funktioniert gut genug. Ich habe jede Callback-log seine pid, Funktionsnamen und args auf der Konsole:

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([]) 

Also dann nenne ich stop:

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> 

depend wird nicht heruntergefahren, und es sitzt nur da an der Schale . Wenn ich die Anwendung mit erlang:exit/2 zwingen zu töten, zum Beispiel, dann bekomme ich das gewünschte Verhalten (abgesehen von der Crash-Dump):

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> 

Aber warum nicht beim Herunter normalerweise nach unten? Es scheint sich als eine oder temporary Anwendung zu verhalten, nicht wie ich permanent erwarten würde, basierend auf was in den Dokumenten geschrieben wird.

Eine zusätzliche Anmerkung, ich bin Version gesperrt zu erts-5.10.4/otp-R16B03-1.

Antwort

3

Nur ein bisschen weiter unten in den gleichen Unterlagen, die Sie zitiert wird geschrieben:

Eine Anwendung kann immer explizit von application:stop/1 Aufruf gestoppt werden. Unabhängig vom Modus sind keine anderen Anwendungen betroffen.

Sie haben dann Recht, dass es nur funktioniert, wenn die Anwendung abnormal gestoppt wird, z. getötet. Siehe this code - Das erste, was OTP beim Beenden einer Anwendung ausführt, ist die Verknüpfung des Prozesses und das Löschen von Informationen, die von der Anwendung ausgeführt werden. Da ein process terminated normally keine Signale erzeugt, die von anderen Prozessen empfangen werden könnten, kann dies zu der Schlussfolgerung führen, dass die Erkennung, wenn abhängige Anwendungen gestoppt werden sollen, von einer Verbindung zwischen der application_controller und der laufenden Anwendung abhängt.

+0

Junge, das ist interessant. Danke für die Köpfe hoch. Ich habe diese Verbindung beim Lesen der Dokumente nicht hergestellt. Gibt es eine bevorzugte Möglichkeit, eine OTP-Anwendung und ihre Abhängigkeiten abzubauen? Ich habe in der Vergangenheit in Deadlock-Probleme application_controller gestoßen, aber jetzt scheint es, dass Anwendung: Stop/1 ist nicht der Weg zu gehen. –

+0

Ich bin nicht sicher, was Sie meinen, indem Sie abreißen. Normalerweise werden die Anwendungen ausgeführt, solange die VM ausgeführt wird. Wenn Sie Anwendungen explizit laden/starten/stoppen/entladen müssen, können Sie dies in den Funktionen "start" und "stop" der Anwendungen tun, zB: https://github.com/amiramix/humbundee/blob/master/lib /humbundee/src/hbd_app.erl#L30 Und Sie können alle Details, einschließlich der Liste der abhängigen Anwendungen, aus der '.app' Datei mit' application: get_all_key (some_app). 'holen, sobald 'some_app' geladen wurde. – Amiramix

Verwandte Themen