Hi,
After building a release with MIX_ENV=prod mix release
, we are informed of the following:
# To stop it gracefully (you may also send SIGINT/SIGTERM)
What are the differences between stopping a release with SIGINT and SIGTERM?
Hi,
After building a release with MIX_ENV=prod mix release
, we are informed of the following:
# To stop it gracefully (you may also send SIGINT/SIGTERM)
What are the differences between stopping a release with SIGINT and SIGTERM?
SIGINT
is supposed to be related to killing a process from inputting characters on the terminal. So if you CTRL+ C
'd a process, that should send a SIGINT
.
I think SIGTERM
is a more of a “hey, let’s shut down this process gracefully” but this is meant to be triggered by another process, such as a process manager.
SIGKILL
on the other hand is a non-graceful event. The OS won’t wait for your process to run any exit routines and will just kill it on the spot. That’s what happens when you run kill -9
on a process.
SIGINT
- “Sorry to interrupt you, sir, but you need to come with Us.”SIGTERM
- “Your contract have been terminated, security will lead you out.”SIGKILL
- BAM!!!
Thank you @cnck1387
I am deploying a release with systemd
and I have a choice to either send a SIGINT
or a SIGTERM
signal to stop the process.
I am asking the initial question because I do notice a difference between the 2 signals.
kill -s SIGINT $(_build/prod/rel/myapp/bin/myapp pid)
gives:
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
kill -s SIGTERM $(_build/prod/rel/myapp/bin/myapp pid)
gives:
:gen_event handler Logger.Backends.Console installed in Logger terminating
** (exit) an exception was raised:
** (Protocol.UndefinedError) protocol String.Chars not implemented for %{tag: :info_msg} of type Map. This protocol is implemented for the following type(s): Postgrex.Query, Postgrex.Copy, Decimal, Time, Float, BitString, Version.Requirement, Version, Atom, Date, URI, Integer, List, NaiveDateTime, DateTime
(elixir 1.10.1) lib/string/chars.ex:3: String.Chars.impl_for!/1
(elixir 1.10.1) lib/string/chars.ex:22: String.Chars.to_string/1
(logger 1.10.1) lib/logger/formatter.ex:180: Logger.Formatter.metadata/1
(logger 1.10.1) lib/logger/formatter.ex:152: anonymous fn/6 in Logger.Formatter.format/5
(elixir 1.10.1) lib/enum.ex:2111: Enum."-reduce/3-lists^foldl/2-0-"/3
(logger 1.10.1) lib/logger/formatter.ex:151: Logger.Formatter.format/5
(logger 1.10.1) lib/logger/backends/console.ex:186: Logger.Backends.Console.format_event/5
(logger 1.10.1) lib/logger/backends/console.ex:140: Logger.Backends.Console.log_event/5
Therefore, SIGTERM
does not produce the same effect as with SIGINT
.
Thank you @hauleth
Is there any documentation in Elixir that explains this with more in-depth technical details? I could not find any myself.
If you were in a terminal and hit CTRL + C
inside of an iex session then you would get the same output as what you’re showing in your SIGINT output where you can pick what option to perform.
I suppose a better way to explain it then is a SIGINT
will provide you the same outcome as if you were to have killed a process with CTRL + C
. I updated my original reply to better reflect that.
I’m guessing the SIGTERM is what you want to have happen? That’s what I would send if I wanted to kill a process from another process.
That is the question I am having myself.
I want to stop the process as gracefully as possible so I would like to know how Elixir/Erlang reacts to such signals and choose what is best in my use case.
man 3 signal
And yes, you want SIGTERM
.
This seems like bug in the Logger. Could you report it and I will check that out.
In general you want to use SIGTERM
unless specified otherwise.
Ok, I dug more and here is what I found:
On Unix systems, the Erlang runtime will interpret two types of signals.
SIGUSR1
A SIGUSR1 signal forces a crash dump.
SIGTERM
A SIGTERM will produce a stop message to the init process. This is equivalent to a init:stop/0 call.
Introduced in ERTS 8.3 (Erlang/OTP 19.3)
source: https://erlang.org/doc/man/erl.html#signals
So I guess, that is the documentation I was looking for.
Yes, I will do that.
Seems that it is already tracked there: https://github.com/elixir-lang/elixir/issues/9814
For the record, migrating from Elixir 1.10.1 to 1.10.2 fixed the problem with the Logger.