Ich schreibe eine Elixir-App mit GenServer, die eine externe Anwendung beim Hochfahren startet und sie herunterfährt und andere Bereinigung beim Beenden durchführt. Ich habe Boot-Funktionalität in der init/1
Rückruf-und Bereinigungscode im terminate/2
Callback hinzugefügt.Graceful shutdown von GenServer
Der init
Code funktioniert gut, wenn die GenServer gestartet wird, und die terminate
Methode wird auch aufgerufen, wenn das :stop
Signal manuell gesendet wird, aber in den Fällen von unerwarteten Abschaltungen und Unterbrechungen (wie im Fall von Drücken von Strg + C) In IEx wird der Beendigungscode nicht aufgerufen.
Derzeit habe ich über Tonnen von Themen im Forum, Blog-Posts und Dokumentation gegangen, darunter:
- Getting Started: GenServers
- Elixir-Lang-Talk: Graceful shutdown of GenServer(s) on exiting iex -S mix
- Elixir-Lang-Talk: Stopping Genserver vs Process.exit
Wenn die
GenServer
ein Signal Ausgang empfängt (dh nicht:normal
) von jedem Prozess, wenn er es nicht verläßt Trapping abrupt mit dem gleichen Grunde verlassen und soterminate/2
nicht nennen. Beachten Sie, dass ein Prozess NICHT Trap beendet standardmäßig und ein Exit-Signal gesendet wird, wenn ein verknüpfter Prozess beendet oder sein Knoten getrennt wird.Daher ist nicht garantiert, dass
terminate/2
aufgerufen wird, wenn einGenServer
beendet wird. Aus diesen Gründen empfehlen wir in der Regel wichtige Clean-up-Regeln in getrennten Prozessen entweder durch Verwendung von Überwachung oder durch Links selbst passieren.
aber ich habe absolut keine Ahnung, wie :init.stop
, linked processes
oder irgendetwas anderes zu bekommen mit diesem zu arbeiten (da dies mein erstes Mal mit GenServers ist).
Dies ist mein Code:
defmodule MyAwesomeApp do
use GenServer
def start do
GenServer.start_link(__MODULE__, nil)
end
def init(state) do
# Do Bootup stuff
IO.puts "Starting: #{inspect(state)}"
{:ok, state}
end
def terminate(reason, state) do
# Do Shutdown Stuff
IO.puts "Going Down: #{inspect(state)}"
:normal
end
end
MyAwesomeApp.start
'Process.flag (: trap_exit, true)' funktioniert nicht für mich. Kannst du mir bitte sagen, wo ich das in einem Genserver nennen soll? – Sheharyar
Sie sollten es in den Prozess setzen, was bedeutet "init/1" – vfsoraki
Versucht, dass das nicht funktioniert. – Sheharyar