Agent
description
Agent module
-
manage state in a process
-
wraps the GenServer behaviour
simple stack with Agent
-
house all Agent calls
-
abstract away how it works under the hood
-
start the Agent as a named process so we can reference the process by name
defmodule MyStack do
use Agent
def start_link(initial_state \\ []) do
# synchronously start the Agent process
Agent.start_link(
fn -> initial_state end,
name: __MODULE__
)
end
def stop do
# synchronously stop the Agent process
Agent.stop(__MODULE__)
end
def push(element) do
Agent.update(
__MODULE__,
fn state -> [element | state] end
)
end
def pop do
# get and update the agent state in one operation
Agent.get_and_update(
__MODULE__,
fn
[] ->
{_result, _new_state} = {{:error, "empty stack"}, []}
[head | rest] ->
{_result, _new_state} = {head, rest}
end
)
end
def inspect do
Agent.get(
__MODULE__,
fn state -> state end
)
end
end
MyStack.start_link([])
MyStack.inspect()
for value <- 1..10 do
MyStack.push(value)
end
MyStack.inspect()
MyStack.pop()
MyStack.stop()
# `use Agent` generates `child_spec/1`
MyStack.child_spec([])
Process introspection
description
-
extract the state of processes
-
see the memory usage of individual processes
-
etc
tools and techniques
MyStack.start_link([])
pid = Process.whereis(MyStack)
Process.info(pid)
:sys.get_state(MyStack)
:sys.replace_state(MyStack, fn state -> [123 | state] end)
:sys.get_status(MyStack)
# List all the PIDs currently executing on the current BEAM instance
Process.list()
# find the process with the largest total heap size
# (how much memory the process is using)
Process.list()
|> Enum.max_by(fn pid -> Process.info(pid, :total_heap_size) end)
|> Process.info()
# find the process with the highest reduction count
Process.list()
|> Enum.max_by(fn pid -> Process.info(pid, :reductions) end)
|> Process.info()