def loop(some_int) do
receive do
{:add, value} ->
loop(some_int + value)
end
end
Stack
serverdefmodule StackServer do
def loop(state) do
receive do
{:push, value} ->
new_state = [value | state]
loop(new_state)
{:pop, sender} ->
[value | new_state] = state
send(sender, value)
loop(new_state)
end
end
end
push
functiondefmodule StackServer do
def push(pid, value) do
send(pid, {:push, value})
end
end
pop
synchronousdefmodule StackServer do
def pop(pid) do
ref = make_ref()
send(pid, {:pop, self(), ref})
receive do
{^ref, value} -> value
end
end
def loop(state) do
receive do
{:pop, sender, ref} ->
[value | new_state] = state
send(sender, {ref, value})
loop(new_state)
end
end
end
Two main primitives
link
: non-stackable bidirectional linkif linked process dies, I must do something
monitor
: stackable unidirectional linkif monitored process dies, it's not really my problem
Default behavior: if you die, I die
iex(1)> spawn_link(fn -> raise "die!" end)
** (EXIT from #PID<0.98.0>) an exception was raised:
** (RuntimeError) die!
(stdlib) erl_eval.erl:668: :erl_eval.do_apply/6
Interactive Elixir (1.4.2) - press Ctrl+C to exit (type h() ENTER for help)
22:27:50.586 [error] Process #PID<0.100.0> raised an exception
** (RuntimeError) die!
(stdlib) erl_eval.erl:668: :erl_eval.do_apply/6
New link behavior: if you die, I get a message
iex(1)> Process.flag(:trap_exit, true)
false
iex(2)> spawn_link(fn -> raise "die!" end)
#PID<0.101.0>
iex(3)>
22:30:04.530 [error] Process #PID<0.101.0> raised an exception
** (RuntimeError) die!
(stdlib) erl_eval.erl:668: :erl_eval.do_apply/6
flush()
{:EXIT, #PID<0.101.0>,
{%RuntimeError{message: "die!"},
[{:erl_eval, :do_apply, 6, [file: 'erl_eval.erl', line: 668]}]}}
Processes are usually divided in two types
Supervisor are responsible for restarting workers
4 main strategies
Given processes A,B,C
, if B
dies
B
A,B,C
B,C
B
Processes in simple one for one must have the same type (i.e. call the same function) and are usually spawned dynamically
Application is usually composed of many supervisors and workers