/var/log/messages

May 29, 2019 - 1 minute read - Comments - programming

プログラミング Elixir (33)

スタックの課題をやってみます。お題てきにスタックのアプリケーションにスーパーバイザを追加、というものです。

とりあえず、元の実装が以下らしい。

defmodule Stack do
  use GenServer

  ### GenServer API

  @doc """
  GenServer.init/1 コールバック
  """
  def init(state), do: {:ok, state}

  @doc """
  GenServer.handle_call/3 コールバック
  """
  def handle_call(:pop, _from, [value | state]) do
    {:reply, value, state}
  end

  def handle_call(:pop, _from, []), do: {:reply, nil, []}

  def handle_call(:stack, _from, state), do: {:reply, state, state}

  @doc """
  GenServer.handle_cast/2 コールバック
  """
  def handle_cast({:push, value}, state) do
    {:noreply, [value] ++ state}
  end

  ### クライアント側API / ヘルパー関数

  def start_link(state \\ []) do
    GenServer.start_link(__MODULE__, state, name: __MODULE__)
  end

  def stack, do: GenServer.call(__MODULE__, :stack)
  def push(value), do: GenServer.cast(__MODULE__, {:push, value})
  def pop, do: GenServer.call(__MODULE__, :pop)
end

これをもとに作成、ってことで Cloud Shell にて以下を実行。

$ mix new --sup stack

上のナニを stack ディレクトリに server.ex を作成して Stack.Server な module として定義。stack/application.ex は以下で良いのかどうか。

  def start(_type, _args) do
    import Supervisor.Spec, warn: false
    # List all child processes to be supervised
    children = [
      # Starts a worker by calling: Stack.Worker.start_link(arg)
      # {Stack.Worker, arg}
      worker(Stack.Server, [], name: SimpleQueue)
    ]

    # See https://hexdocs.pm/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: Stack.Supervisor]
    Supervisor.start_link(children, opts)
  end

ありゃ、落ちないな。

Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Stack.Server.push 1
:ok
iex(2)> Stack.Server.pop 
1
iex(3)> Stack.Server.pop
nil

とりあえず、こうして

#  def handle_call(:pop, _from, []), do: {:reply, nil, []}

落ちて復活、を確認。

これを元にして

状態を管理、なナニを作ってみる方向で。

囲碁本 環境構築

comments powered by Disqus