Manuel Albarran

A random notes about Elixir

Asyncs calls to any GenServer

14 Feb 2017 » elixir, GenServer
defmodule PingPong do
  use GenServer
  def handle_call(:ping, _from, i), do: :timer.sleep(500) && {:reply, "pong-#{i}", i + 1}
end

defmodule Async do
  def call(pid, val), do: send(pid, {:"$gen_call", {self, make_ref}, val}) |> elem(1) |> elem(1)
  def value(ref), do: receive do {ref, value} -> value  end
end

defmodule Main do
  def run do
    {:ok, pingpong1} = GenServer.start_link(PingPong, 10)
    IO.inspect(v1_1 = Async.call(pingpong1, :ping))
    IO.inspect(v2_1 = Async.call(pingpong1, :ping))
    IO.inspect(v3_1 = Async.call(pingpong1, :ping))
    {:ok, pingpong2} = GenServer.start_link(PingPong, 20)
    IO.inspect(v1_2 = Async.call(pingpong2, :ping))
    IO.inspect(v2_2 = Async.call(pingpong2, :ping))
    IO.inspect(v3_2 = Async.call(pingpong2, :ping))

    :timer.sleep(1_000)

    IO.inspect(v1_1 |> Async.value)
    IO.inspect(v2_1 |> Async.value)
    IO.inspect(v3_1 |> Async.value)
    IO.inspect(v1_2 |> Async.value)
    IO.inspect(v2_2 |> Async.value)
    IO.inspect(v3_2 |> Async.value)
  end
end

Main.run