intro to otp in elixir

82

Upload: jesse-anderson

Post on 16-Apr-2017

71 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Intro to OTP in Elixir
Page 2: Intro to OTP in Elixir
Page 3: Intro to OTP in Elixir

OTP

• Erlang

• Tools

• Libraries

• Design Principles

• Other Stuff

Page 4: Intro to OTP in Elixir

Processes

Page 5: Intro to OTP in Elixir

iex(1)>

Page 6: Intro to OTP in Elixir

iex(1)> spawn(fn -> IO.puts “Hello Full Stack” end)

Page 7: Intro to OTP in Elixir

iex(1)> spawn(fn -> IO.puts “Hello Full Stack” end)

Hello Full Stack

#PID<0.64.0>

iex(2)>

Page 8: Intro to OTP in Elixir

iex(2)> pid = spawn(fn -> IO.puts “Hello Full Stack” end)

Hello Full Stack

#PID<0.65.0>

iex(3)> Process.alive?(pid)

false

iex(4)>

Page 9: Intro to OTP in Elixir

Error Handling

Page 10: Intro to OTP in Elixir

Supervisors

Page 11: Intro to OTP in Elixir
Page 12: Intro to OTP in Elixir

“The Zen of Erlang”

Page 13: Intro to OTP in Elixir
Page 14: Intro to OTP in Elixir
Page 15: Intro to OTP in Elixir
Page 16: Intro to OTP in Elixir
Page 17: Intro to OTP in Elixir

Messages

Page 18: Intro to OTP in Elixir

FantasyTeam

Page 19: Intro to OTP in Elixir

State

Page 20: Intro to OTP in Elixir

defmodule FantasyTeam.Basic do

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end end

Page 21: Intro to OTP in Elixir

defmodule FantasyTeam.Basic do

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do

...

Page 22: Intro to OTP in Elixir

defmodule FantasyTeam.Basic do

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do

...

Page 23: Intro to OTP in Elixir

defmodule FantasyTeam.Basic do

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do

...

Page 24: Intro to OTP in Elixir

defmodule FantasyTeam.Basic do

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do

...

Page 25: Intro to OTP in Elixir

defmodule FantasyTeam.Basic do

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do

...

Page 26: Intro to OTP in Elixir

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, state)

loop(new_state)

Page 27: Intro to OTP in Elixir

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, state)

loop(new_state)

Page 28: Intro to OTP in Elixir

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, state)

loop(new_state)

Page 29: Intro to OTP in Elixir

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, state)

loop(new_state)

Page 30: Intro to OTP in Elixir

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, state)

loop(new_state)

Page 31: Intro to OTP in Elixir

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, state)

loop(state)

Page 32: Intro to OTP in Elixir

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, state)

loop(state)

Page 33: Intro to OTP in Elixir

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, state)

loop(state)

Page 34: Intro to OTP in Elixir

iex(1)>

Page 35: Intro to OTP in Elixir

iex(1)> pid = FantasyTeam.Basic.start_link

#PID<0.65.0>

iex(2)>

Page 36: Intro to OTP in Elixir

iex(1)> pid = FantasyTeam.Basic.start_link

#PID<0.65.0>

iex(2)> send(pid, {:add, “Russell Wilson”})

{:add, “Russell Wilson”}

iex(3)>

Page 37: Intro to OTP in Elixir

iex(1)> pid = FantasyTeam.Basic.start_link

#PID<0.65.0>

iex(2)> send(pid, {:add, “Russell Wilson”})

{:add, “Russell Wilson”}

iex(3)> send(pid, {:add, “Doug Baldwin”})

{:add, “Doug Baldwin”}

iex(4)>

Page 38: Intro to OTP in Elixir

iex(1)> pid = FantasyTeam.Basic.start_link

#PID<0.65.0>

iex(2)> send(pid, {:add, “Russell Wilson”})

{:add, “Russell Wilson”}

iex(3)> send(pid, {:add, “Doug Baldwin”})

{:add, “Doug Baldwin”}

iex(4)> send(pid, {:remove, “Doug Baldwin”})

{:remove, “Doug Baldwin”}

iex(5)>

Page 39: Intro to OTP in Elixir

iex(1)> pid = FantasyTeam.Basic.start_link

#PID<0.65.0>

iex(2)> send(pid, {:add, “Russell Wilson”})

{:add, “Russell Wilson”}

iex(3)> send(pid, {:add, “Doug Baldwin”})

{:add, “Doug Baldwin”}

iex(4)> send(pid, {:remove, “Doug Baldwin”})

{:remove, “Doug Baldwin”}

iex(5)> send(pid, {:team, self})

{:team, #PID<0.123.0>}

iex(6)>

Page 40: Intro to OTP in Elixir

iex(1)> pid = FantasyTeam.Basic.start_link

#PID<0.65.0>

iex(2)> send(pid, {:add, “Russell Wilson”})

{:add, “Russell Wilson”}

iex(3)> send(pid, {:add, “Doug Baldwin”})

{:add, “Doug Baldwin”}

iex(4)> send(pid, {:remove, “Doug Baldwin”})

{:remove, “Doug Baldwin”}

iex(5)> send(pid, {:team, self})

{:team, #PID<0.123.0>}

iex(6)> flush

{:ok, %{“Russell Wilson” => %{position: “QB”, team: “SEA”}}

Page 41: Intro to OTP in Elixir

defmodule FantasyTeam.Basic do

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end end

Page 42: Intro to OTP in Elixir

GenServer

Page 43: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) end

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end end

defmodule FantasyTeam.Basic do

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end end

Page 44: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

defmodule FantasyTeam.Basic do

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player)

loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name)

loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end end

Page 45: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 46: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 47: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 48: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 49: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 50: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 51: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 52: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 53: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 54: Intro to OTP in Elixir

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end

def start_link do spawn_link(__MODULE__, :loop, [%{}]) end

def loop(state) do receive do {:add, name} -> player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) loop(new_state)

{:remove, name} -> new_state = Map.delete(state, name) loop(new_state)

{:team, pid} -> send(pid, {:ok, state})

loop(state) end end

Page 55: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 56: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 57: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 58: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 59: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 60: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 61: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 62: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 63: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 64: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 65: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 66: Intro to OTP in Elixir

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

def init(:ok) do {:ok, %{}} end

def handle_cast({:add, name}, state) do player = FantasyTeam.Player.find(name) new_state = Map.put(state, name, player) {:noreply, new_state} end

def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end

def handle_call(:team, _from, state) do {:reply, state, state} end end

Page 67: Intro to OTP in Elixir

defmodule FantasyTeam.SingleServer do use GenServer

@name __MODULE__

# API

def start_link do GenServer.start_link(__MODULE__, :ok, name: @name) end

def add(name) do GenServer.cast(@name, {:add, name}) def

def remove(name) do GenServer.cast(@name, {:remove, name}) end

def team do GenServer.call(@name, :team) end

# Callbacks

...

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 68: Intro to OTP in Elixir

defmodule FantasyTeam.SingleServer do use GenServer

@name __MODULE__

# API

def start_link do GenServer.start_link(__MODULE__, :ok, name: @name) end

def add(name) do GenServer.cast(@name, {:add, name}) def

def remove(name) do GenServer.cast(@name, {:remove, name}) end

def team do GenServer.call(@name, :team) end

# Callbacks

...

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 69: Intro to OTP in Elixir

defmodule FantasyTeam.SingleServer do use GenServer

@name __MODULE__

# API

def start_link do GenServer.start_link(__MODULE__, :ok, name: @name) end

def add(name) do GenServer.cast(@name, {:add, name}) def

def remove(name) do GenServer.cast(@name, {:remove, name}) end

def team do GenServer.call(@name, :team) end

# Callbacks

...

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 70: Intro to OTP in Elixir

defmodule FantasyTeam.SingleServer do use GenServer

@name __MODULE__

# API

def start_link do GenServer.start_link(__MODULE__, :ok, name: @name) end

def add(name) do GenServer.cast(@name, {:add, name}) def

def remove(name) do GenServer.cast(@name, {:remove, name}) end

def team do GenServer.call(@name, :team) end

# Callbacks

...

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 71: Intro to OTP in Elixir

defmodule FantasyTeam.SingleServer do use GenServer

@name __MODULE__

# API

def start_link do GenServer.start_link(__MODULE__, :ok, name: @name) end

def add(name) do GenServer.cast(@name, {:add, name}) def

def remove(name) do GenServer.cast(@name, {:remove, name}) end

def team do GenServer.call(@name, :team) end

# Callbacks

...

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 72: Intro to OTP in Elixir

defmodule FantasyTeam.SingleServer do use GenServer

@name __MODULE__

# API

def start_link do GenServer.start_link(__MODULE__, :ok, name: @name) end

def add(name) do GenServer.cast(@name, {:add, name}) def

def remove(name) do GenServer.cast(@name, {:remove, name}) end

def team do GenServer.call(@name, :team) end

# Callbacks

...

defmodule FantasyTeam.MyGenServer do use GenServer

# API

def start_link do GenServer.start_link(__MODULE__, :ok, []) end

def add(pid, name) do GenServer.cast(pid, {:add, name}) def

def remove(pid, name) do GenServer.cast(pid, {:remove, name}) end

def team(pid) do GenServer.call(pid, :team) end

# Callbacks

...

Page 73: Intro to OTP in Elixir

iex(1)>

Page 74: Intro to OTP in Elixir

iex(1)> FantasyTeam.SingleServer.start_link

{:ok, #PID<0.65.0>}

iex(2)>

Page 75: Intro to OTP in Elixir

iex(1)> FantasyTeam.SingleServer.start_link

{:ok, #PID<0.65.0>}

iex(2)> FantasyTeam.SingleServer.add(“Russell Wilson”)

:ok

iex(3)>

Page 76: Intro to OTP in Elixir

iex(1)> FantasyTeam.SingleServer.start_link

{:ok, #PID<0.65.0>}

iex(2)> FantasyTeam.SingleServer.add(“Russell Wilson”)

:ok

iex(3)> FantasyTeam.SingleServer.add(“Doug Baldwin”)

:ok

iex(4)>

Page 77: Intro to OTP in Elixir

iex(1)> FantasyTeam.SingleServer.start_link

{:ok, #PID<0.65.0>}

iex(2)> FantasyTeam.SingleServer.add(“Russell Wilson”)

:ok

iex(3)> FantasyTeam.SingleServer.add(“Doug Baldwin”)

:ok

iex(4)> FantasyTeam.SingleServer.remove(“Doug Baldwin”)

:ok

iex(5)>

Page 78: Intro to OTP in Elixir

iex(1)> FantasyTeam.SingleServer.start_link

{:ok, #PID<0.65.0>}

iex(2)> FantasyTeam.SingleServer.add(“Russell Wilson”)

:ok

iex(3)> FantasyTeam.SingleServer.add(“Doug Baldwin”)

:ok

iex(4)> FantasyTeam.SingleServer.remove(“Doug Baldwin”)

:ok

iex(5)> FantasyTeam.SingleServer.team

%{“Russell Wilson” => %{position: “QB”, team: “SEA”}}

iex(6)>

Page 79: Intro to OTP in Elixir

Recap

Page 80: Intro to OTP in Elixir

Agents & Tasks

Page 81: Intro to OTP in Elixir

defmodule FantasyTeam.MyAgent do

def start_link do Agent.start_link(fn -> %{} end) end

def add(pid, name) do player = FantasyTeam.Player.find(name) Agent.get_and_update(pid, fn(x) -> {player, Map.put(x, name, player)} end) :ok end

def remove(pid, name) do Agent.update(pid, fn(x) -> Map.delete(x, name) end) end

def team(pid) do Agent.get(pid, fn(x) -> x end) end end

Page 82: Intro to OTP in Elixir

bit.ly/fullstackotpOTP / ELIXIR RESOURCES

@jessejandersonFOLLOW ME