Elixir v1.14 + Livebook
Mix.install([
{:kino, github: "livebook-dev/kino", override: true},
{:kino_vega_lite, "~> 0.1.3"},
{:kino_db, "~> 0.1.2"},
{:postgrex, "~> 0.16.3"}
])
Autocompletion
Hit tab after the dot below:
String.
Processes
self()
parent = self()
child =
spawn(fn ->
receive do
:ping ->
Process.sleep(2_000)
send(parent, :pong)
end
end)
send(child, :ping)
receive do
:pong -> :ponged!
end
Kino.Process.render_seq_trace(fn ->
parent = self()
child =
spawn(fn ->
receive do
:ping -> send(parent, :pong)
end
end)
send(child, :ping)
receive do
:pong -> :ponged!
end
end)
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)
Supervisors
{:ok, supervisor} =
Supervisor.start_link(
[
{Task, fn -> Process.sleep(:infinity) end},
{Agent, fn -> [] end}
],
strategy: :one_for_one
)
Kino.Process.render_sup_tree(supervisor)
supervisor
Kino.Process.render_app_tree(:kino)
:kino
Kino.Supervisor
dbg
"Elixir is cool!"
|> String.trim_trailing("!")
|> String.split()
|> List.first()
|> dbg()
Chart: Memory x Reductions
processes =
for pid <- Process.list() do
info = Process.info(pid, [:reductions, :memory, :status])
%{
pid: inspect(pid),
reductions: info[:reductions],
memory: info[:memory],
status: info[:status]
}
end
alias VegaLite, as: Vl
Vl.new(width: 600, height: 400)
|> Vl.data_from_values(processes)
|> Vl.mark(:point, tooltip: true)
|> Vl.encode_field(:x, "reductions", type: :quantitative, scale: [type: "log", base: 10])
|> Vl.encode_field(:y, "memory", type: :quantitative, scale: [type: "log", base: 10])
|> Vl.encode_field(:color, "status", type: :nominal)
|> Vl.encode_field(:tooltip, "pid", type: :nominal)
Chart: memory over time
:erlang.memory()
memory_plot =
Vl.new(width: 600, height: 400, padding: 20)
|> Vl.repeat(
[layer: ["total", "processes", "atom", "binary", "code", "ets"]],
Vl.new()
|> Vl.mark(:line)
|> Vl.encode_field(:x, "iter", type: :quantitative, title: "Measurement")
|> Vl.encode_repeat(:y, :layer, type: :quantitative, title: "Memory usage (MB)")
|> Vl.encode(:color, datum: [repeat: :layer], type: :nominal)
)
|> Kino.VegaLite.new()
Kino.VegaLite.periodically(memory_plot, 200, 1, fn i ->
point =
:erlang.memory()
|> Enum.map(fn {type, bytes} -> {type, bytes / 1_000_000} end)
|> Map.new()
|> Map.put(:iter, i)
Kino.VegaLite.push(memory_plot, point, window: 1000)
{:cont, i + 1}
end)
Binary usage
for i <- 1..10_000 do
String.duplicate("cat", i)
end
ETS usage
tid = :ets.new(:users, [:set, :public])
for i <- 1..1_000_000 do
:ets.insert(tid, {i, "User #{i}"})
end
Smart cells
Mouse over and press “+ Smart” and choose “Chart” to plot processes!