Top Banner
Elixir Elevated The Ups and Downs of OTP Greg Vaughn [email protected] twitter: @gregvaughn, github/irc: gvaughn
40

Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Aug 27, 2014

Download

Software

Greg Vaughn

Conference talk given at the inaugural ElixirConf 2014 in Austin, TX
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Elixir Elevated!The Ups and Downs of OTP

Greg [email protected]!

twitter: @gregvaughn, github/irc: gvaughn

Page 2: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Student of Elixir and OTP!Hobbying with Elixir almost 13 months!Texan!Professional Programmer of 20 years!Across 6 languages!Employed by LivingSocial

Page 3: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Student of Elixir and OTP!Hobbying with Elixir almost 13 months!Texan!Professional Programmer of 20 years!Across 6 languages!Employed by LivingSocial

LivingSocial is Hiring!

Page 4: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

OTP is …

Page 5: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

OTP is …

Mature / Battle Tested for 16 (18?) years

Page 6: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

OTP is …

Mature / Battle Tested for 16 (18?) years

Microservices

Page 7: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

OTP is …

Mature / Battle Tested for 16 (18?) years

Microservices

Object Oriented (NOT class oriented)

Page 8: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

OTP is …

Mature / Battle Tested for 16 (18?) years

Microservices

Object Oriented (NOT class oriented)

Actor

Page 9: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

OTP is …

Mature / Battle Tested for 16 (18?) years

Microservices

Object Oriented (NOT class oriented)

Actor

Framework (Hollywood Principle)

Page 10: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

OTP is …

Mature / Battle Tested for 16 (18?) years

Microservices

Object Oriented (NOT class oriented)

Actor

Framework (Hollywood Principle)

Design Patterns

Page 11: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

OTP is …

Mature / Battle Tested for 16 (18?) years

Microservices

Object Oriented (NOT class oriented)

Actor

Framework (Hollywood Principle)

Design Patterns

Robust

Page 12: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

object oriented

OOP to me means only messaging, local retention and protection and !

hiding of state-process, and extreme late-binding of all things. — Alan Kay

Page 13: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

object oriented

OOP to me means only messaging, local retention and protection and !

hiding of state-process, and extreme late-binding of all things. — Alan Kay

functional

a style of building the structure and elements of computer programs that treats computation as the evaluation of mathematical functions and avoids state and mutable data. — Wikipedia

Page 14: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

object oriented

OOP to me means only messaging, local retention and protection and !

hiding of state-process, and extreme late-binding of all things. — Alan Kay

functional

a style of building the structure and elements of computer programs that treats computation as the evaluation of mathematical functions and avoids state and mutable data. — Wikipedia

concurrent

The conceptually simultaneous execution of more than one sequential program on a computer or network of computers. — McGraw-Hill Sci & Tech

Dictionary

Page 15: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

object oriented functional

concurrent

actors

Page 16: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Behaviours: Don’t call us, we’ll call you

defmodule MyCallback do use GenServer end

iex> {:ok, pid} = GenServer.start(MyCallback, [])

Page 17: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Behaviours: Don’t call us, we’ll call you

defmodule MyCallback do use GenServer end

iex> {:ok, pid} = GenServer.start(MyCallback, [])

defmodule GenServer do defmacro __using__(_) do     quote do       @behaviour :gen_server !      def init(args), do: {:ok, args} !      def handle_cast(msg, state), do: {:stop, {:bad_cast, msg}, state} !      def handle_call(msg, _from, state), do: {:stop, {:bad_call, msg}, state} !      def handle_info(_msg, state), do: {:noreply, state} !      def terminate(_reason, _state), do: :ok !      def code_change(_old, state, _extra), do: {:ok, state} !      defoverridable [init: 1, handle_call: 3, handle_info: 2,                       handle_cast: 2, terminate: 2, code_change: 3]     end   end … end

Page 18: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

defmodule MyCallback do use GenServer @initial_state %{} ! def start_link do GenServer.start_link(__MODULE__, @initial_state) end ! def init(arg) do state = arg {:ok, state} end ! def do_it(pid, param) do GenServer.call(pid, {:do_it, param}) end ! def handle_call({:do_it, param}, _from, state) do payload = get_payload(param, state) new_state = update_state(param, state) {:reply, payload, new_state} end ! defp get_payload(param, state), do: “I DONE DID IT!” ! defp update_state(param, state), do: state end

Page 19: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

defmodule MyCallback do use GenServer @initial_state %{} ! def start_link do GenServer.start_link(__MODULE__, @initial_state) end ! def init(arg) do state = arg {:ok, state} end ! def do_it(pid, param) do GenServer.call(pid, {:do_it, param}) end ! def handle_call({:do_it, param}, _from, state) do payload = get_payload(param, state) new_state = update_state(param, state) {:reply, payload, new_state} end ! defp get_payload(param, state), do: “I DONE DID IT!” ! defp update_state(param, state), do: state end

Page 20: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

defmodule MyCallback do use GenServer @initial_state %{} ! def start_link do GenServer.start_link(__MODULE__, @initial_state) end ! def init(arg) do state = arg {:ok, state} end ! def do_it(pid, param) do GenServer.call(pid, {:do_it, param}) end ! def handle_call({:do_it, param}, _from, state) do payload = get_payload(param, state) new_state = update_state(param, state) {:reply, payload, new_state} end ! defp get_payload(param, state), do: “I DONE DID IT!” ! defp update_state(param, state), do: state end

Page 21: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

defmodule MyCallback do use GenServer @initial_state %{} ! def start_link do GenServer.start_link(__MODULE__, @initial_state) end ! def init(arg) do state = arg {:ok, state} end ! def do_it(pid, param) do GenServer.call(pid, {:do_it, param}) end ! def handle_call({:do_it, param}, _from, state) do payload = get_payload(param, state) new_state = update_state(param, state) {:reply, payload, new_state} end ! defp get_payload(param, state), do: “I DONE DID IT!” ! defp update_state(param, state), do: state end

Page 22: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

defmodule MyCallback do use GenServer @initial_state %{} ! def start_link do GenServer.start_link(__MODULE__, @initial_state) end ! def init(arg) do state = arg {:ok, state} end ! def do_it(pid, param) do GenServer.call(pid, {:do_it, param}) end ! def handle_call({:do_it, param}, _from, state) do payload = get_payload(param, state) new_state = update_state(param, state) {:reply, payload, new_state} end ! defp get_payload(param, state), do: “I DONE DID IT!” ! defp update_state(param, state), do: state end

Clie

nt P

roce

ssServer Process

Page 23: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Elevators 101

Page 24: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

A rider on any floor presses the up or down button!An elevator car arrives!Rider enters and presses a destination floor button

rider hall!signal

hall!signal car

carrider

floor hail

retrieve

arrival

arrivalgo to

Page 25: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

A rider on any floor presses the up or down button!An elevator car arrives!Rider enters and presses a destination floor button

rider hall!signal

hall!signal car

carrider

floor hail

retrieve

arrival

arrivalgo to

Hailstruct

Page 26: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Show Me The Code

Page 27: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Let It Fail … and Respond

Separation of Concerns!

Think Long and Hard about Failure Response!

BEAM (not OS) Processes!

Finer Grained Control

Page 28: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Prepare to Fail

Car!Supervisor

Car 1 Car n…

one_for_one

Page 29: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Prepare to Fail

Car!Supervisor

Car 1 Car n…

one_for_one

Hall!Signal

Page 30: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Prepare to Fail

Car!Supervisor

Car 1 Car n…

one_for_one

Gen!Event

Hall!Signal

Page 31: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Prepare to Fail

Car!Supervisor

Car 1 Car n…

one_for_one

Gen!Event

Hall!Signal

Bank!Supervisor

rest_for_one

Page 32: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Prepare to Fail

Gen!Event HS

Bank A!Supervisor

CSGen!

Event HS

Bank B!Supervisor

CS

Elevator!Supervisor

one_for_one

Page 33: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Prepare to Fail

Gen!Event HS

Bank A!Supervisor

CSGen!

Event HS

Bank B!Supervisor

CS

Elevator!Supervisor

one_for_one

GenEvent

GenEvent

Page 34: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Don’t Tripdefmodule MySupervisor do use Supervisor ! def init(…) do workers = worker(MyCallback, [p1, p2, [name: :myc]], [id: :mine]) supervise(workers, strategy: one_for_one) end end !defmodule MyCallback do use GenServer ! def start_link(p1, p2, opts \\ []) GenServer.start_link(__MODULE__, [p1, p2], opts) end ! def init([p1, p2]) do {:ok, %{p1: p1, p2: p2}} end end

Page 35: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Don’t Tripdefmodule MySupervisor do use Supervisor ! def init(…) do workers = worker(MyCallback, [p1, p2, [name: :myc]], [id: :mine]) supervise(workers, strategy: one_for_one) end end !defmodule MyCallback do use GenServer ! def start_link(p1, p2, opts \\ []) GenServer.start_link(__MODULE__, [p1, p2], opts) end ! def init([p1, p2]) do {:ok, %{p1: p1, p2: p2}} end end

apply: list of params

Page 36: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Don’t Tripdefmodule MySupervisor do use Supervisor ! def init(…) do workers = worker(MyCallback, [p1, p2, [name: :myc]], [id: :mine]) supervise(workers, strategy: one_for_one) end end !defmodule MyCallback do use GenServer ! def start_link(p1, p2, opts \\ []) GenServer.start_link(__MODULE__, [p1, p2], opts) end ! def init([p1, p2]) do {:ok, %{p1: p1, p2: p2}} end end

apply: list of params

single term for init/1

Page 37: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Trip-less Convention?defmodule MySupervisor do use Supervisor ! def init(…) do workers = worker(MyCallback, [{p1, p2}, name: :myc], [id: :mine]) supervise(workers, strategy: one_for_one) end end !defmodule MyCallback do use GenServer ! def start_link(init_params, opts \\ []) GenServer.start_link(__MODULE__, init_params, opts) end ! def init({p1, p2}) do {:ok, %{p1: p1, p2: p2}} end end

Page 38: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Show Me The Code

Page 39: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Takeaways

Behaviours vs. Callback Modules!

Watch your initialization steps!

Watch parameter and return value contracts!

Supervisors and Strategies!

Config

Page 40: Elixir Elevated: The Ups and Downs of OTP at ElixirConf2014

Thank you

Elixir Elevated!The Ups and Downs of OTP!!Greg [email protected]!twitter: @gregvaughn!github/irc: gvaughn

http://github.com/gvaughn/elixir_elevated/tree/elixirconf2014