Last active
July 21, 2022 11:12
-
-
Save amokan/a9d63786fbed7a215030f11a8e93aab7 to your computer and use it in GitHub Desktop.
Comparison of GenServer state orchestration using send/2 vs the new handle_continue callback
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 GroceryCart do | |
@moduledoc """ | |
Simple example showing the `handle_continue` callback in Erlang/OTP 21+ | |
""" | |
use GenServer | |
# simple contrived struct for state - didn't need to be a struct at all | |
defstruct items: [] | |
@doc """ | |
Start a new instance of the Grocery Cart server | |
""" | |
def start_link, do: GenServer.start_link(__MODULE__, :ok, name: __MODULE__) | |
@doc false | |
def init(_) do | |
{:ok, %__MODULE__{}, {:continue, :add_cheese}} | |
end | |
@doc false | |
def handle_continue(:add_cheese, %__MODULE__{items: items} = state) do | |
updated_state = %__MODULE__{state | items: ["cheese" | items]} | |
{:noreply, updated_state, {:continue, :add_milk}} | |
end | |
@doc false | |
def handle_continue(:add_milk, %__MODULE__{items: items} = state) do | |
updated_state = %__MODULE__{state | items: ["milk" | items]} | |
{:noreply, updated_state, {:continue, :print_and_exit}} | |
end | |
@doc false | |
def handle_continue(:print_and_exit, %__MODULE__{items: items} = state) do | |
IO.inspect(items, label: "Items") | |
IO.puts("Will Exit Now") | |
{:stop, :normal, 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 GroceryCartOld do | |
@moduledoc """ | |
Simple example showing how to orchestrate a GenServer progressing it's own state | |
""" | |
use GenServer | |
# simple contrived struct for state - didn't need to be a struct at all | |
defstruct items: [] | |
@doc """ | |
Start a new instance of the Grocery Cart server | |
""" | |
def start_link, do: GenServer.start_link(__MODULE__, :ok, name: __MODULE__) | |
@doc false | |
def init(_) do | |
# queues up a msg to itself using `send()` which will be picked up by a `handle_info/2` callback | |
send(self(), :add_cheese) | |
{:ok, %__MODULE__{}} | |
end | |
@doc false | |
def handle_info(:add_cheese, %__MODULE__{items: items} = state) do | |
updated_state = %__MODULE__{state | items: ["cheese" | items]} | |
# queues up a msg to itself using `send()` which will be picked up by a `handle_info/2` callback | |
send(self(), :add_milk) | |
{:noreply, updated_state} | |
end | |
@doc false | |
def handle_info(:add_milk, %__MODULE__{items: items} = state) do | |
updated_state = %__MODULE__{state | items: ["milk" | items]} | |
# queues up a msg to itself using `Process.send_after()` with a delay of 1 second - this will be picked up by a `handle_info/2` callback | |
Process.send_after(self(), :print_and_exit, 1_000) | |
{:noreply, updated_state} | |
end | |
@doc false | |
def handle_info(:print_and_exit, %__MODULE__{items: items} = state) do | |
IO.inspect(items, label: "Items") | |
IO.puts("Will Exit Now") | |
{:stop, :normal, state} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment