Mix . install ( [
{ :kino , github: "livebook-dev/kino" , ref: "hb-support-process-labels" }
] )
Kino.Process.render_seq_trace
parent = self ( )
Kino.Process . render_seq_trace ( fn ->
child =
spawn ( fn ->
Process . set_label ( :ponger )
receive do
:ping ->
# Process.sleep(1)
send ( parent , :pong )
end
end )
send ( child , :ping )
receive do
:pong -> :ponged!
end
end )
Ping pong with ponger outside traced function
parent = self ( )
child =
spawn ( fn ->
Process . set_label ( :ponger )
receive do
:ping ->
Process . sleep ( 1 ) # theres's a race condition here
send ( parent , :pong )
end
end )
Kino.Process . render_seq_trace ( fn ->
send ( child , :ping )
receive do
:pong -> :ponged!
end
end )
Ping pong with ponger as genserver (long living process)
defmodule Worker do
use GenServer
def start_link ( opts ) do
GenServer . start_link ( __MODULE__ , opts )
end
@ impl true
def init ( opts ) do
if label = Keyword . get ( opts , :label ) do
Process . set_label ( label )
end
{ :ok , opts }
end
@ impl true
def handle_info ( { :ping , from } , opts ) do
send ( from , :pong )
{ :noreply , opts }
end
end
worker = Kino . start_child! ( { Worker , [ label: "my worker" ] } )
Kino.Process . render_seq_trace ( fn ->
send ( worker , { :ping , self ( ) } )
receive do
:pong -> :ponged!
end
end )
Ping pong with ponger as task with receive loop
parent = self ( )
process_label = "ponger"
ponger_pid =
Task . async ( fn ->
Process . set_label ( process_label )
receive_loop = fn f ->
receive do
:ping ->
send ( parent , :pong )
f . ( f )
end
end
receive_loop . ( receive_loop )
end ) . pid
trace_function = fn ->
send ( ponger_pid , :ping )
receive do
:pong -> :ponged!
end
end
# trace_function.()
Kino.Process . render_seq_trace ( trace_function )
Kino.Process.render_sup_tree
# Stop the supervisor if it is already running
if is_pid ( Process . whereis ( :supervisor_parent ) ) do
Supervisor . stop ( :supervisor_parent )
end
supervision_tree_with_children = % {
id: Supervisor ,
start:
{ Supervisor , :start_link ,
[
[
% { id: :child , start: { Agent , :start_link , [ fn -> :ok end , [ name: :agent_child ] ] } } ,
% { id: 1 , start: { Worker , :start_link , [ [ label: { "tuple label" , 2 } ] ] } } ,
% { id: 2 , start: { Worker , :start_link , [ [ label: :atom_label ] ] } } ,
% { id: 3 , start: { Worker , :start_link , [ [ label: "string label" ] ] } } ,
% { id: 4 , start: { Worker , :start_link , [ [ ] ] } }
] ,
[ name: :supervisor_parent , strategy: :one_for_one ]
] } ,
restart: :temporary
}
pid = Kino . start_child! ( supervision_tree_with_children )
Kino.Process . sup_tree ( pid )
supervision_tree_with_ets_table = % {
id: Supervisor ,
start:
{ Supervisor , :start_link ,
[
[
{ Agent , fn -> :ok end } ,
% {
id: :ets_heir ,
start: { Agent , :start_link , [ fn -> :ok end , [ name: :ets_heir ] ] }
} ,
% {
id: :ets_owner ,
start:
{ Agent , :start_link ,
[
fn ->
heir_pid = Process . whereis ( :ets_heir )
:ets . new (
:test_ets_table ,
[ :set , :protected , :named_table , { :heir , heir_pid , nil } ]
)
end ,
[ name: :ets_owner ]
] }
} ,
% { id: 11 , start: { Worker , :start_link , [ [ label: { "tuple label" , 2 } ] ] } } ,
] ,
[ name: :supervisor_parent_ets , strategy: :one_for_one ]
] } ,
restart: :temporary
}
pid_with_ets = Kino . start_child! ( supervision_tree_with_ets_table )
Kino.Process . sup_tree ( pid_with_ets , render_ets_tables: true )
With not started processes
defmodule TransientWorker do
use GenServer
def start_link ( opts ) do
GenServer . start_link ( __MODULE__ , opts )
end
@ impl true
def init ( opts ) do
if label = Keyword . get ( opts , :label ) do
Process . set_label ( label )
end
:ignore
# {:ok, opts}
end
end
# Stop the supervisor if it is already running
if is_pid ( Process . whereis ( :supervisor_parent_transiet_worker ) ) do
Supervisor . stop ( :supervisor_parent_transiet_worker )
end
supervision_tree_with_children = % {
id: Supervisor ,
start:
{ Supervisor , :start_link ,
[
[
% { id: 11 , start: { Worker , :start_link , [ [ label: { "tuple label" , 2 } ] ] } } ,
% { id: 12 , start: { Worker , :start_link , [ [ label: :atom_label ] ] } } ,
# %{id: 13, start: {TransientWorker, :start_link, [[label: "string label"]]}}
{ TransientWorker , [ label: "string label" ] }
] ,
[ name: :supervisor_parent_transiet_worker , strategy: :one_for_one ]
] } ,
restart: :temporary
}
pid = Kino . start_child! ( supervision_tree_with_children )
Kino.Process . sup_tree ( pid )