Skip to content

Instantly share code, notes, and snippets.

View TylerPachal's full-sized avatar

Tyler Pachal TylerPachal

View GitHub Profile
# Create a long enough string that it will be stored off of this process' heap
iex(1)> long_binary = "This is a long binary that will need to be at least 64 bytes in length"
"This is a long binary that will need to be at least 64 bytes in length"
# Verify that our string is longer than 64 bytes
iex(2)> byte_size(long_binary)
70
# Inspect the IEx process' binary info. We can see our binary is there by correlating the 70 byte
# length. The tuple that is returned is of the form {binary id, byte length, reference count}. So
def init(type) do
Logger.info("#{type} - init start")
state = %{
type: type,
data: nil
}
Logger.info("#{type} - init end")
# Modified return value that will trigger the handle_continue callback
def start(_type, _args) do
children = [
Spammer, # New process
Supervisor.child_spec({MyServer, :users}, id: make_ref()),
Supervisor.child_spec({MyServer, :messages}, id: make_ref()),
Supervisor.child_spec({MyServer, :items}, id: make_ref())
]
opts = [strategy: :one_for_one, name: ContinueTest.Supervisor]
Supervisor.start_link(children, opts)
defmodule MyServer do
# ...
# Some sort of async operation that needs to be done on the data
def handle_cast({:increment, id}, state) do
Logger.info("#{state.type} - increment #{id}")
updated_data = Map.update(state.data, id, 1, fn v -> v + 1 end)
updated_state = Map.put(state, :data, updated_data)
{:noreply, updated_state}
end
def init(type) do
Logger.info("#{type} - init start")
state = %{
type: type,
data: nil
}
# Send a message to ourself to load the data outside of the synchronous
# init block
self() |> send(:more_init)
defmodule HandleContinueBlogpost.ApplicationSlowSync do
use Application
defmodule MyServer do
use GenServer
require Logger
def start_link(type) do
GenServer.start_link(__MODULE__, type, name: type)
end
def join_game(user_id, game_id) do
with {:user, {:ok, user}} <- get_user(user_id),
{:game, {:ok, game}} <- get_game(game_id),
# Etc...
end
defp get_user(id) do
{:user, Users.get(id)}
end
def join_game(user_id, game_id) do
with {:ok, user} <- Users.get(user_id),
{:ok, game} <- Games.get(game_id),
false <- Game.is_full?(game),
false <- Game.is_started?(game),
true <- User.has_permission?(user, game)
do
Game.add_user(game, user)
else
# Don't care what specific thing failed
# I don't want to have to do this in other parts of my code,
# this function should clearly just return a boolean value.
{_, res} = Game.is_started?(game)
def join_game(user_id, game_id) do
with {:user, {:ok, user}} <- {:user, Users.get(user_id)},
{:game, {:ok, game}} <- {:game, Games.get(game_id)},
{:full, false} <- {:full, Game.is_full?(game)},
{:started, false} <- {:started, Game.is_started?(game)},
{:allowed, true} <- {:allowed, User.has_permission?(user, game)}
do
Game.add_user(game, user)
else
{:user, :not_found} -> {:error, "User not found"}