I have a question regarding server termination vs server exit.
I would appreciate that this question be considered in light of the below code and excerpt.
defmodule Duper.Worker do
use GenServer, restart: :transient
def start_link(_) do
GenServer.start_link(__MODULE__, :no_args)
end
def init(:no_args) do
Process.send_after(self(), :do_one_file, 0)
{ :ok, nil }
end
def handle_info(:do_one_file, _) do
Duper.PathFinder.next_path()
|> add_result()
end
defp add_result(nil) do
Duper.Gatherer.done()
{:stop, :normal, nil}
end
defp add_result(path) do
Duper.Gatherer.result(path, hash_of_file_at(path))
send(self(), :do_one_file)
{ :noreply, nil }
end
defp hash_of_file_at(path) do
File.stream!(path, [], 1024*1024)
|> Enum.reduce(
:crypto.hash_init(:md5),
fn (block, hash) ->
:crypto.hash_update(hash, block)
end)
|> :crypto.hash_final()
end
end
Why Can’t We Just Write a Looping Function?
We can implement a loop in Elixir using a recursive function call.
But the worker server doesn’t do this. Instead, it sends itself a
message and then exits after processing each file.The reason is that the Elixir runtime won’t let any one invocation of
a server hog the CPU forever. Instead it sets a timeout on each call
or cast into a GenServer (by default 5 seconds). If the call or cast
handler has not returned in that time, the runtime assumes
something has gone wrong and terminates the server.
Processing a million files in a loop will take more than 5 seconds.
So we instead just process one file per entry into the server, and then
queue up another message to process the next on a fresh entry. The
result: no timeouts.
My question is regarding the bolded and italicised statement. My understanding was that a Gen server exited by returning :stop, :terminate, or calling System.halt(num), however the explanation suggests that the server exits implicitly, so I wonder if exiting and terminating are different.
Also just prior to when server is said to exit, it sends itself the :do_one_file atom, but the init of the server already does this, so the server can not be terminating and reinitialising since the sending of such a message when would not be necessary at termination as it also takes place at initialisation.
There definitely seems to be a difference between exiting and termianting, I would appreciate some clarity on the difference(s).