Fun With Elixir OTP by Daniel Jaouen


Today we’re going to be studying Elixir’s OTP facilities. First, key this in as lib/supervisor_test/server.ex:

defmodule SupervisorTest.Server do
  use GenServer

  def start_link(pid) do
    GenServer.start_link(__MODULE__, [pid])

  def get_pid(pid) do, :get_pid)

  def init([pid]) do
    {:ok, pid}

  def handle_call(:get_pid, _from, pid) do
    {:reply, pid, pid}

  def handle_call(message, from, pid) do
    {:reply, pid, pid}

  def handle_info(:stop, pid) do
    {:stop, "GenServer stopped", pid}

First, we notice we have the standard API call to GenServer.start_link. This function implicitly calls init. Then we have an API call (get_pid) that runs a, :get_pid). The rest of the file is pretty straightforward.

Then, key this in as lib/supervisor_test/supervisor.ex:

defmodule SupervisorTest.Supervisor do
  use Supervisor

  def start_link do
    Supervisor.start_link(__MODULE__, [4, 5, 6, 7])

  def init(args) do
    worker_opts = [restart: :permanent]
    workers = [
      worker(SupervisorTest.Server, [self()], worker_opts),
    opts = [strategy: :simple_one_for_one,
            max_restarts: 5,
            max_seconds: 5]
    supervise(workers, opts)

First, we have an API call to Supervisor.start_link with args [4, 5, 6, 7]. This function implicitly calls init. We then IO.inspect args and then start the supervision tree. Notice that we’re using a :simple_one_for_one server here, meaning the child will need to be started manually.

Now, key this in as lib/supervisor_test.ex:

defmodule SupervisorTest do
  use Application

  def start(type, args) do

We see here that we’re first examining the type and args args in start. We then make our API call to SupervisorTest.Supervisor.start_link.

Now key this in as mix.exs:

defmodule SupervisorTest.Mixfile do
  use Mix.Project

  def project do
      app: :supervisor_test,
      version: "0.1.0",
      elixir: "~> 1.5",
      start_permanent: Mix.env == :prod,
      deps: deps()

  # Run "mix help" to learn about applications.
  def application do
      extra_applications: [:logger],
      mod: {SupervisorTest, [1, 2, 3, 4]}

  # Run "mix help deps" to learn about dependencies.
  defp deps do
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "", tag: "0.1.0"},

We see here that we’re starting SupervisorTest with the arguments [1, 2, 3, 4].

Run up an iex -S mix session and key these commands in:

○ iex -S mix
Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

[1, 2, 3, 4]
[4, 5, 6, 7]
Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> {:ok, supervisor} = SupervisorTest.Supervisor.start_link
[4, 5, 6, 7]
{:ok, #PID<0.115.0>}
iex(2)> Supervisor.which_children(supervisor)
iex(3)> {:ok, server} = Supervisor.start_child(supervisor, [])
{:ok, #PID<0.118.0>}
iex(4)> SupervisorTest.Server.get_pid(server)
iex(5)> send server, :stop
08:39:29.525 [error] GenServer #PID<0.118.0> terminating
** (stop) "GenServer stopped"
Last message: :stop
State: #PID<0.115.0>
[{:undefined, #PID<0.121.0>, :worker, [SupervisorTest.Server]}]
iex(7)> server = supervisor |> Supervisor.which_children |> |> elem(1)
iex(8)> SupervisorTest.Server.get_pid(server)

We see that immediately :normal, [1, 2, 3, 4] and [4, 5, 6, 7] are printed out. This is expected because we IO.inspect type and args in SupervisorTest.start and then IO.inspect args in SupervisorTest.Supervisor.init.

We then manually fire up a new SupervisorTest.Supervisor by calling the associated start_link function. We notice [4, 5, 6, 7] is printed out again (which makes sense because we’re calling IO.inspect(args) in SupervisorTest.Supervisor.init). We then call Supervisor.which_children and (as expected) we see no started children. We then manually start the child process with a call to Supervisor.start_child and capture its pid.

We then call SupervisorTest.Server.get_pid(server), which sends a :get_pid call to server. We get back the supervisor’s pid, as expected. We then send a :stop message to the server, which stops the server. The next call to Supervisor.which_children shows that we successfullly restarted the process (as expected). We then call server = supervisor |> Supervisor.which_children |> |> elem(1) to capture the new server process and call get_pid, which returns the supervisor’s pid, as expected.

And that’s it. I hope you found this useful. Feel free to leave comments below.



входные двери с зеркалом металлические двери брак установка дверей в киеве установка межкомнатных дверей витебск правильно установленная межкомнатная дверь кнопочный замок на входную дверь межкомнатные двери с врезанной фурнитурой производим металлические двери межкомнатные двери корона направляющие для межкомнатных дверей

сборка межкомнатной двери запорный механизм балконной двери металлопластиковые балконные двери цена железные двери москва и область двери железные москва двери стальные входные металлические могилев купить дверь входную в витебске купить входную дверь в беларуси фиксатор балконной двери пвх купить двери пвх окна пвх

Page 1