The ABCs of OTP

Post on 09-Apr-2017

20 views 0 download

Transcript of The ABCs of OTP

What is OTP anyway?

What is OTP anyway?

(basically)

Collection of libraries

Hierarchy of supervisors & workers

Main OTP Libraries

Supervisor

Main OTP Libraries

Supervisor

GenServer

Main OTP Libraries

Supervisor

GenServer

Agent & Task

Main OTP Components

(and other stuff like GenStage, GenEvent, GenFSM, etc)

Main OTP Components

(and other stuff like GenStage, GenEvent, GenFSM, etc)

Main OTP Components

(and other stuff like GenStage, GenEvent, GenFSM, etc)

Main OTP Components

(and other stuff like GenStage, GenEvent, GenFSM, etc)

(and more stuff like Application, ETS, Mnesia)

Main OTP Components

(and other stuff like GenStage, GenEvent, GenFSM, etc)

(and more stuff like Application, ETS, Mnesia)

(even more stuff like Dialyzer, gen_tcp, Observer)

Main OTP Components

Supervisor

GenServer

Agent & Task

Processes

iex(1)>

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

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

Hello ElixirDaze

#PID<0.64.0>

iex(2)>

iex(2)>

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

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

Hello ElixirDaze

#PID<0.65.0>

iex(3)>

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

Hello ElixirDaze

#PID<0.65.0>

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

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

Hello ElixirDaze

#PID<0.65.0>

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

false

iex(4)>

Error Handling

Supervisors

“The Zen of Erlang”

Messages

FantasyTeam

State

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

defmodule FantasyTeam.Basic do

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

def loop(state) do

...

defmodule FantasyTeam.Basic do

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

def loop(state) do

...

defmodule FantasyTeam.Basic do

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

def loop(state) do

...

defmodule FantasyTeam.Basic do

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

def loop(state) do

...

defmodule FantasyTeam.Basic do

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

def loop(state) do

...

defmodule FantasyTeam.Basic do

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

def loop(state) do

...

> FantasyTeam.Basic.loop(%{})

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)

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)

FantasyTeam.Player.find("Russell Wilson")

%{ active: "1", college: "Wisconsin", display_name: "Russell Wilson", dob: “1988-11-29”, fname: "Russell", height: "5-11", jersey: "3", lname: "Wilson", player_id: "1847", position: "QB", team: "SEA", weight: "206" }

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)

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)

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)

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)

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)

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)

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)

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)

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

iex(1)>

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

#PID<0.65.0>

iex(2)>

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

#PID<0.65.0>

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

{:add, “Russell Wilson”}

iex(3)>

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)>

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)>

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)>

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”, ...}}

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

GenServer

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

...

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

...

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

...

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

...

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

...

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

...

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

...

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

...

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

...

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

...

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

...

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

...

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.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}) end

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}) end

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

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

# Callbacks

...

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}) end

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}) end

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

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

# Callbacks

...

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}) end

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}) end

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

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

# Callbacks

...

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}) end

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}) end

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

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

# Callbacks

...

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}) end

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}) end

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

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

# Callbacks

...

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}) end

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}) end

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

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

# Callbacks

...

iex(1)>

iex(1)> FantasyTeam.SingleServer.start_link

{:ok, #PID<0.65.0>}

iex(2)>

iex(1)> FantasyTeam.SingleServer.start_link

{:ok, #PID<0.65.0>}

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

:ok

iex(3)>

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)>

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)>

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)>

Agents & Tasks

defmodule FantasyTeam.MyAgent do @name __MODULE__

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

def add(name) do player = FantasyTeam.Player.find(name) Agent.update(@name, fn(x) -> Map.put(x, name, player)} end) end

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

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

defmodule FantasyTeam.MyAgent do @name __MODULE__

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

def add(name) do player = FantasyTeam.Player.find(name) Agent.update(@name, fn(x) -> Map.put(x, name, player)} end) end

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

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

Supervisors

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

defmodule FantasyTeam.MySupervisor do use Supervisor

def start_link do Supervisor.start_link(__MODULE__, []) end

def init([]) do children = [ worker(FantasyTeam.SingleServer, []) ]

supervise(children, strategy: :one_for_one) end end

Recap

r

bit.ly/abcs-of-otpOTP / ELIXIR RESOURCES

@jessejandersonFOLLOW ME