Last active
July 20, 2019 23:21
-
-
Save soonernotfaster/d7a06e591d8e6c6926cc89ae7da3ecd0 to your computer and use it in GitHub Desktop.
What Is A GenServer?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # test/account_test.exs | |
| defmodule AccountTest do | |
| use ExUnit.Case | |
| test "fails" do | |
| assert true == false | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def get_balance(pid) do | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def get_balance(pid) do | |
| 0 | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def init(:ok) do | |
| {:ok, %{balance: 0}} | |
| end | |
| # ... | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def get_balance(pid) do | |
| GenServer.call(pid, :get_balance) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_call(:get_balance, _from, state) do | |
| {:reply, Map.get(state, :balance), state} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule AccountTest do | |
| use ExUnit.Case | |
| # ... | |
| test 'depositing money changes the balance' do | |
| {:ok, pid} = Account.start_link | |
| Account.deposit(pid, 10.0) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account | |
| def deposit(pid, amount) do | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule AccountTest do | |
| # ... | |
| test 'depositing money changes the balance' do | |
| {:ok, pid} = Account.start_link | |
| Account.deposit(pid, 10.0) | |
| assert 10.0 == Account.get_balance(pid) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def deposit(pid, amount) do | |
| GenServer.cast(pid, {:deposit, amount}) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:deposit, amount}, state) do | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:deposit, amount}, state) do | |
| {:noreply, state} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:deposit, amount}, state) do | |
| balance = Map.get(state, :balance) | |
| {:noreply, Map.put(state, :balance, balance + amount)} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:deposit, amount}, state) do | |
| {_value, balance_with_deposit} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, balance + amount} | |
| end) | |
| {:noreply, balance_with_deposit} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule AccountTest do | |
| # ... | |
| test 'withdraw money reduces the balance' do | |
| {:ok, pid} = Account.start_link() | |
| Account.withdraw(pid, 52.34) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def withdraw(pid, amount) do | |
| end | |
| # ... | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule AccountTest do | |
| # ... | |
| test 'withdraw money reduces the balance' do | |
| {:ok, pid} = Account.start_link() | |
| Account.withdraw(pid, 52.34) | |
| assert -52.34 == Account.get_balance(pid) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def withdraw(pid, amount) do | |
| GenServer.cast(pid, {:withdraw, amount}) | |
| end | |
| # ... | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:deposit, amount}, state) do | |
| # ... | |
| end | |
| def handle_cast({:withdraw, amount}, state) do | |
| {:noreply, state} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:deposit, amount}, state) do | |
| {_value, balance_with_deposit} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, balance + amount} | |
| end) | |
| {:noreply, balance_with_deposit} | |
| end | |
| def handle_cast({:withdraw, amount}, state) do | |
| {_value, balance_with_deposit} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, balance - amount} | |
| end) | |
| {:noreply, balance_with_deposit} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:deposit, amount}, state) do | |
| # Extracted anonymous function | |
| update_balance = fn balance, amount -> balance + amount end | |
| {_value, balance_with_deposit} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| # we now call the function instead of doing a calculation | |
| {balance, update_balance.(balance, amount)} | |
| end) | |
| {:noreply, balance_with_deposit} | |
| end | |
| # similar changes were made to this function | |
| def handle_cast({:withdraw, amount}, state) do | |
| update_balance = fn balance, amount -> balance - amount end | |
| {_value, balance_with_deposit} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, update_balance.(balance, amount)} | |
| end) | |
| {:noreply, balance_with_deposit} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule AccountTest do | |
| use ExUnit.Case | |
| test "initial balance is zero" do | |
| {:ok, pid} = Account.start_link | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule AccountTest do | |
| use ExUnit.Case | |
| test "initial balance is zero" do | |
| {:ok, pid} = Account.start_link() | |
| assert 0 == Account.get_balance(pid) | |
| end | |
| test 'depositing money changes the balance' do | |
| {:ok, pid} = Account.start_link() | |
| Account.deposit(pid, 10.0) | |
| assert 10.0 == Account.get_balance(pid) | |
| end | |
| test 'withdraw money reduces the balance' do | |
| {:ok, pid} = Account.start_link() | |
| Account.withdraw(pid, 52.34) | |
| assert -52.34 == Account.get_balance(pid) | |
| end | |
| end | |
| defmodule Account do | |
| # ... | |
| def handle_cast({:deposit, amount}, state) do | |
| update_balance = fn balance, amount -> balance + amount end | |
| # variable 'update_balance' changed to 'updated_balance' | |
| {_value, updated_balance} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, update_balance.(balance, amount)} | |
| end) | |
| # variable name changed | |
| {:noreply, updated_balance} | |
| end | |
| def handle_cast({:withdraw, amount}, state) do | |
| update_balance = fn balance, amount -> balance - amount end | |
| # variable name changed | |
| {_value, updated_balance} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, update_balance.(balance, amount)} | |
| end) | |
| # variable name changed | |
| {:noreply, updated_balance} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:withdraw, amount}, state) do | |
| update_balance = fn balance, amount -> balance - amount end | |
| {:noreply, change_balance(state, amount, update_balance)} | |
| end | |
| # extracted function | |
| defp change_balance(state, amount, update_balance) do | |
| {_value, updated_balance} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, update_balance.(balance, amount)} | |
| end) | |
| updated_balance | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:withdraw, amount}, state) do | |
| {:noreply, change_balance(state, amount, &(&1 - &2))} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| defp change_balance(state, amount, calculate_balance) do | |
| {_value, updated_balance} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, calculate_balance.(balance, amount)} | |
| end) | |
| updated_balance | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def handle_cast({:withdraw, amount}, state) do | |
| {:noreply, get_updated_balance(state, amount, &(&1 - &2))} | |
| end | |
| defp get_updated_balance(state, amount, calculate_balance) do | |
| {_value, updated_balance} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, calculate_balance.(balance, amount)} | |
| end) | |
| updated_balance | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| # notice the only different is in the anonymous function | |
| def handle_cast({:deposit, amount}, state) do | |
| {:noreply, get_updated_balance(state, amount, &(&1 + &2))} | |
| end | |
| def handle_cast({:withdraw, amount}, state) do | |
| {:noreply, get_updated_balance(state, amount, &(&1 - &2))} | |
| end | |
| #... | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| use GenServer | |
| def start_link do | |
| GenServer.start_link(__MODULE__, :ok) | |
| end | |
| def init(:ok) do | |
| {:ok, %{balance: 0}} | |
| end | |
| # API | |
| def get_balance(pid) do | |
| GenServer.call(pid, :get_balance) | |
| end | |
| def deposit(pid, amount) do | |
| GenServer.cast(pid, {:deposit, amount}) | |
| end | |
| def withdraw(pid, amount) do | |
| GenServer.cast(pid, {:withdraw, amount}) | |
| end | |
| # Callbacks | |
| def handle_call(:get_balance, _from, state) do | |
| {:reply, Map.get(state, :balance), state} | |
| end | |
| def handle_cast({:deposit, amount}, state) do | |
| {:noreply, get_updated_balance(state, amount, &(&1 + &2))} | |
| end | |
| def handle_cast({:withdraw, amount}, state) do | |
| {:noreply, get_updated_balance(state, amount, &(&1 - &2))} | |
| end | |
| # private | |
| defp get_updated_balance(state, amount, calculate_balance) do | |
| {_value, updated_balance} = | |
| Map.get_and_update(state, :balance, fn balance -> | |
| {balance, calculate_balance.(balance, amount)} | |
| end) | |
| updated_balance | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # bank/lib/account.ex | |
| defmodule Account | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # lib\account.ex | |
| defmodule Account do | |
| def start_link do | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| use GenServer | |
| def start_link do | |
| GenServer.start_link(__MODULE__, :ok) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def init(:ok) do | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Account do | |
| # ... | |
| def init(:ok) do | |
| {:ok, %{}} | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # test\account_test.exs | |
| defmodule AccountTest do | |
| use ExUnit.Case | |
| test "initial balance is zero" do | |
| {:ok, pid} = Account.start_link | |
| assert 0 == Account.get_balance(pid) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| This is a list of code samples for my post about writing GenServers with TDD. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment