Slide 1

Slide 1 text

SUPERVISORS, LINKS & MONITORS Sean Cribbs

Slide 2

Slide 2 text

FLASHBACK: 2008 a more innocent time

Slide 3

Slide 3 text

PLAYSKOOL: MY FIRST ERLANG twitter client mochiweb handler mnesia

Slide 4

Slide 4 text

PLAYSKOOL: MY FIRST ERLANG ➤ Twitter API changes? CRASH twitter client mochiweb handler mnesia

Slide 5

Slide 5 text

PLAYSKOOL: MY FIRST ERLANG ➤ Twitter API changes? CRASH ➤ Buggy request handler? CRASH twitter client mochiweb handler mnesia

Slide 6

Slide 6 text

PLAYSKOOL: MY FIRST ERLANG ➤ Twitter API changes? CRASH ➤ Buggy request handler? CRASH ➤ Mnesia acting weird? CRASH twitter client mochiweb handler mnesia

Slide 7

Slide 7 text

PLAYSKOOL: MY FIRST ERLANG ➤ Twitter API changes? CRASH ➤ Buggy request handler? CRASH ➤ Mnesia acting weird? CRASH twitter client mochiweb handler mnesia RESULT: Unpredictable behavior

Slide 8

Slide 8 text

SUPERVISORS are not for restarting processes

Slide 9

Slide 9 text

SUPERVISORS are for structuring your application

Slide 10

Slide 10 text

HINDSIGHT IS 20/20 twitter client mochiweb handler mnesia my_app (supervisor)

Slide 11

Slide 11 text

HINDSIGHT IS 20/20 ➤ mnesia as application dependency twitter client mochiweb handler mnesia my_app (supervisor)

Slide 12

Slide 12 text

HINDSIGHT IS 20/20 ➤ mnesia as application dependency ➤ Client and mochiweb handler as children twitter client mochiweb handler mnesia my_app (supervisor)

Slide 13

Slide 13 text

HINDSIGHT IS 20/20 ➤ mnesia as application dependency ➤ Client and mochiweb handler as children ➤ Supervisor initializes mnesia tables twitter client mochiweb handler mnesia my_app (supervisor)

Slide 14

Slide 14 text

HINDSIGHT IS 20/20 ➤ mnesia as application dependency ➤ Client and mochiweb handler as children ➤ Supervisor initializes mnesia tables twitter client mochiweb handler mnesia RESULT: Reliability my_app (supervisor)

Slide 15

Slide 15 text

:observer.start()

Slide 16

Slide 16 text

SUPERVISOR STRATEGIES ➤ :one_for_one ➤ :one_for_all ➤ :rest_for_one ➤ :simple_one_for_one

Slide 17

Slide 17 text

SUPERVISOR STRATEGIES ➤ :one_for_one ➤ :one_for_all ➤ :rest_for_one ➤ :simple_one_for_one 㱺 Task.Supervisor

Slide 18

Slide 18 text

SUPERVISORS use links and trap exits

Slide 19

Slide 19 text

LINKS intertwine fates of two processes

Slide 20

Slide 20 text

A B

Slide 21

Slide 21 text

A B Process.link(b)

Slide 22

Slide 22 text

file_server_2 Port (driver)

Slide 23

Slide 23 text

file_server_2 Port (driver) shutdown!

Slide 24

Slide 24 text

file_server_2 Port (driver) shutdown! EXIT close()

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

TRAP EXITS if you need to handle exit signals

Slide 27

Slide 27 text

TRAP EXITS if you need to handle exit signals Process.flag(:trap_exit, true)

Slide 28

Slide 28 text

TRAP EXITS if you need to handle exit signals Process.flag(:trap_exit, true) {:EXIT, pid, reason}

Slide 29

Slide 29 text

MONITORS notify of process exit without linking

Slide 30

Slide 30 text

A B

Slide 31

Slide 31 text

A B Process.monitor(b)

Slide 32

Slide 32 text

A B Process.monitor(b) {:DOWN, ref, :process, pid, reason}

Slide 33

Slide 33 text

A B GENSERVER.CALL/3

Slide 34

Slide 34 text

A B GENSERVER.CALL/3 ➤ Monitor the target {:ok, ref} = Process.monitor(b)

Slide 35

Slide 35 text

A B GENSERVER.CALL/3 ➤ Monitor the target ➤ Send the message tagged with the monitor reference {:ok, ref} = Process.monitor(b) {:'$gen_call', {a, ref}, :hi}

Slide 36

Slide 36 text

A B GENSERVER.CALL/3 ➤ Monitor the target ➤ Send the message tagged with the monitor reference ➤ Receive {:ok, ref} = Process.monitor(b) {:'$gen_call', {a, ref}, :hi}

Slide 37

Slide 37 text

A B GENSERVER.CALL/3 ➤ Monitor the target ➤ Send the message tagged with the monitor reference ➤ Receive ➤ {^ref, reply} ⇒ 
 {:ok, reply} {:ok, ref} = Process.monitor(b) {:'$gen_call', {a, ref}, :hi}

Slide 38

Slide 38 text

A B GENSERVER.CALL/3 ➤ Monitor the target ➤ Send the message tagged with the monitor reference ➤ Receive ➤ {^ref, reply} ⇒ 
 {:ok, reply} ➤ :DOWN ⇒ exit(reason) {:ok, ref} = Process.monitor(b) {:'$gen_call', {a, ref}, :hi}

Slide 39

Slide 39 text

A B GENSERVER.CALL/3 ➤ Monitor the target ➤ Send the message tagged with the monitor reference ➤ Receive ➤ {^ref, reply} ⇒ 
 {:ok, reply} ➤ :DOWN ⇒ exit(reason) ➤ timeout ⇒ exit(:timeout) {:ok, ref} = Process.monitor(b) {:'$gen_call', {a, ref}, :hi}

Slide 40

Slide 40 text

registry conn
 sup app sup CUSTOM PROCESS REGISTRY

Slide 41

Slide 41 text

registry conn
 sup app sup CUSTOM PROCESS REGISTRY ➤ GOAL: Lookup or start a connection to another node

Slide 42

Slide 42 text

registry conn
 sup app sup CUSTOM PROCESS REGISTRY ➤ GOAL: Lookup or start a connection to another node ➤ Client (GenServer.call) ⇒ Registry client

Slide 43

Slide 43 text

registry conn
 sup app sup CUSTOM PROCESS REGISTRY ➤ GOAL: Lookup or start a connection to another node ➤ Client (GenServer.call) ⇒ Registry ➤ Registry ⇒ Supervisor.start_child client

Slide 44

Slide 44 text

registry conn
 sup app sup CUSTOM PROCESS REGISTRY ➤ GOAL: Lookup or start a connection to another node ➤ Client (GenServer.call) ⇒ Registry ➤ Registry ⇒ Supervisor.start_child conn client

Slide 45

Slide 45 text

registry conn
 sup app sup CUSTOM PROCESS REGISTRY ➤ GOAL: Lookup or start a connection to another node ➤ Client (GenServer.call) ⇒ Registry ➤ Registry ⇒ Supervisor.start_child ➤ Registry ⇒ monitor connection conn client

Slide 46

Slide 46 text

registry conn
 sup app sup CUSTOM PROCESS REGISTRY ➤ GOAL: Lookup or start a connection to another node ➤ Client (GenServer.call) ⇒ Registry ➤ Registry ⇒ Supervisor.start_child ➤ Registry ⇒ monitor connection ➤ Client ⇐ connection pid 
 (maybe monitor?) conn client

Slide 47

Slide 47 text

registry conn
 sup app sup CUSTOM PROCESS REGISTRY ➤ GOAL: Lookup or start a connection to another node ➤ Client (GenServer.call) ⇒ Registry ➤ Registry ⇒ Supervisor.start_child ➤ Registry ⇒ monitor connection ➤ Client ⇐ connection pid 
 (maybe monitor?) ➤ DOWN ⇒ Registry cleans up client

Slide 48

Slide 48 text

TIPS AND TRICKS ➤ Don’t put too much on your Supervisor ➤ Child order matters ➤ Use links and monitors ➤ Read the Elixir and Erlang source

Slide 49

Slide 49 text

REFERENCES ➤ Erlang Reference Manual: Processes
 http://erlang.org/doc/reference_manual/processes.html ➤ Erlang Reference Manual: Errors
 http://erlang.org/doc/reference_manual/errors.html ➤ OTP Design Principles: Overview
 http://erlang.org/doc/design_principles/des_princ.html ➤ OTP Design Principles: Supervisors
 http://erlang.org/doc/design_principles/sup_princ.html ➤ OTP Design Principles: Applications
 http://erlang.org/doc/design_principles/applications.html