890a030664f1e2b994d9ac32beace23557d51793 — Alexander Wong 2 years ago 9f59c39
Linking Processes
2 files changed, 61 insertions(+), 0 deletions(-)

A lib/servy/kickstarter.ex
M README.md => README.md +32 -0
@@ 979,3 979,35 @@ Defined a new GenServer `Servy.SensorServer` that does long polling to periodica
The `handle_info` function is used to trigger off a `:refresh` event every 5 seconds. The refresh event will fetch from the mock external API and store the results into a cache.

Be sure to add a `handle_info` function that is generic after adding the new `:refresh` handler, in order to make your server robust to crashes (a new message of `:boom` will throw a FunctionClauseError because nothing will match with `:boom` otherwise).

### Linking Processes

When an Elixir process terminates, it will notify its linked processes by sending it an exit signal.
If the process terminates normally, the exit signal reason is the atom `:normal`.
Because the process exits normally, the linked process does not terminate.

If the process has an abnormal termination, the exit reason will be anything other than `:normal`. By default, the exit signal indicates that the process terminated abnormally and the linked process will terminate with the same reason *unless* the linked process is trapping exits.

Linked processes are always bidirectional.

#### Linking Tasks

Referring back to `Task.async` for spawning functions and `Task.await` for waiting for the results:

iex> pid = Task.async(fn -> Servy.Tracker.get_location("bigfoot") end)

iex> Task.await(pid)
%{lat: "29.0469 N", lng: "98.8667 W"}

The spawned process is automatically linked to the calling process.
If the spawned task process crashes, then the process that calls `Task.async` will also crash.

iex> pid = Task.async(fn -> raise "Kaboom!" end)

** (EXIT from #PID<0.368.0>) evaluator process exited with reason: an exception was raised:
    ** (RuntimeError) Kaboom!

A lib/servy/kickstarter.ex => lib/servy/kickstarter.ex +29 -0
@@ 0,0 1,29 @@
defmodule Servy.KickStarter do
  use GenServer

  def start do
    IO.puts("Starting the kickstarter...")
    GenServer.start(__MODULE__, :ok, name: __MODULE__)

  def init(:ok) do
    Process.flag(:trap_exit, true)
    {:ok, start_server()}

  def handle_info({:EXIT, _pid, reason}, _state) do
    IO.puts("HttpServer exited (#{inspect(reason)})")
    {:noreply, start_server()}

  def start_server do
    IO.puts("Starting the HTTP server...")

    # server_pid = spawn(Servy.HttpServer, :start, [4000])
    # Process.link(server_pid)
    server_pid = spawn_link(Servy.HttpServer, :start, [4000])

    Process.register(server_pid, :http_server)