Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Meta Programmable Functional Notebooks

elixir/concurrency.livemd

Meta Programmable Functional Notebooks

Mix.install([
  {:kino, "~> 0.9.0"}
])

Section

for _ <- 1..1_000_000 do
  spawn(fn -> :ok end)
end
child =
  spawn(fn ->
    receive do
      {:ping, caller} -> send(caller, {:pong})
    end
  end)

send(child, {:ping, self()})

receive do
  {:pong} -> :it_worked!
end

Livebook can help developers see how processes communicate between eachother

Kino.Process.render_seq_trace(fn ->
  child =
    spawn(fn ->
      receive do
        {:ping, from} -> send(from, :pong)
      end
    end)

  send(child, {:ping, self()})

  receive do
    :pong -> :it_worked!
  end
end)

A developer can also observe how Elixir can perform multiple tasks at once, scaling on both CPU and IO

Kino.Process.render_seq_trace(fn ->
  1..4
  |> Task.async_stream(
    fn _ -> Process.sleep(Enum.random(100..300)) end,
    max_concurrency: 4
  )
  |> Stream.run()
end)

Messages can also be distributed across nodes. Here the notebook tries to use a Distributed module but it does not exist

Distributed.hello_world()

If the Distributed module is defined in another notebook (another Erlang VM instance), it could be used via an :erpc call

node =
  Kino.Input.text("Node")
  |> Kino.render()
  |> Kino.Input.read()
  |> String.to_atom()

cookie =
  Kino.Input.text("Cookie")
  |> Kino.render()
  |> Kino.Input.read()
  |> String.to_atom()

Node.set_cookie(node, cookie)
:erpc.call(node, Distributed, :hello_world, [])