Peeper.Supervisor (peeper v0.3.1)

View Source

Supervisor for the Peeper framework that manages the state-preserving GenServer processes.

Overview

The Peeper.Supervisor is a key component in the Peeper architecture, responsible for:

  1. Creating and supervising a supervision tree for each Peeper.GenServer instance
  2. Managing the relationship between the worker process and state keeper process
  3. Ensuring state is preserved between crashes
  4. Handling process transfers between supervisors

Supervision Strategy

By default, Peeper.Supervisor uses a :one_for_one supervision strategy with the following configuration:

  • max_restarts: 1,000 (number of restarts allowed in a time period)
  • max_seconds: 10 (the time period for max_restarts)
  • auto_shutdown: :never (supervisor won't shut down automatically when a child terminates)

This strategy allows individual worker processes to crash and be restarted independently, while the state keeper process remains alive to provide the preserved state on restart.

Children

The supervisor manages two worker processes:

  1. Peeper.State - Preserves the state between crashes
  2. Peeper.Worker - The actual GenServer implementation that delegates to your module

State Preservation Mechanism

When a worker process crashes:

  1. The supervisor detects the crash and initiates a restart
  2. The new worker process starts and requests its previous state from the state keeper
  3. The state keeper provides the preserved state
  4. The worker process resumes operation with the preserved state

This handshake between the worker and state keeper happens transparently and enables the "Let It Crash" philosophy without losing valuable state.

Configuration

When starting a Peeper.Supervisor, you can provide the following configuration options:

  • strategy: The restart strategy (default: :one_for_one)
  • max_restarts: Maximum number of restarts allowed in a time period (default: 1,000)
  • max_seconds: The time period for max_restarts (default: 10)
  • auto_shutdown: Supervisor shutdown behavior when a child terminates (default: :never)

Internal Architecture

Peeper.Supervisor (one_for_one)
 Peeper.State (preserves state)
 Peeper.Worker (runs user callbacks)
     User's Peeper.GenServer implementation

This modular architecture allows for:

  • Independent restart of workers without losing state
  • Clean separation of concerns
  • ETS table preservation between crashes
  • Process dictionary persistence

Summary

Functions

Returns a specification to start this module under a supervisor.

Starts a supervisor linked to the current process.

Gets the PID of the state keeper process for the given Peeper supervisor.

Returns a local or remote pid if the GenServer is alive, nil otherwise

Lists the children, awaiting for all to be restarted successfully.

Gets the PID of the worker process for the given Peeper supervisor.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)

Starts a supervisor linked to the current process.

Options

  • name: Name to register the supervisor (required)
  • impl: The module implementing Peeper.GenServer callbacks (required)
  • state: Initial state for the GenServer (required)
  • strategy, max_restarts, max_seconds, auto_shutdown: Standard supervisor configuration options
  • Any other options are passed to the Worker process

Returns

  • {:ok, pid} if the supervisor is started successfully
  • {:error, {:already_started, pid}} if the supervisor is already started
  • {:error, term} if supervision setup fails

state(pid, delay \\ 0)

Gets the PID of the state keeper process for the given Peeper supervisor.

Parameters

  • pid: PID or registered name of the Peeper supervisor
  • delay: Optional delay in milliseconds before attempting to get the state keeper PID

Returns

PID of the state keeper process

whereis(server)

@spec whereis(server :: pid() | GenServer.name() | {atom(), node()}) :: pid() | nil

Returns a local or remote pid if the GenServer is alive, nil otherwise

which_children(server, delay \\ 0)

Lists the children, awaiting for all to be restarted successfully.

worker(pid, delay \\ 0)

Gets the PID of the worker process for the given Peeper supervisor.

This function is useful when you need to interact directly with the worker GenServer process using standard GenServer functions, bypassing Peeper's wrappers.

Parameters

  • pid: PID or registered name of the Peeper supervisor
  • delay: Optional delay in milliseconds before attempting to get the worker PID

Returns

PID of the worker process

Example

# Get the worker pid and use it directly with GenServer
worker_pid = Peeper.Supervisor.worker(my_peeper_process)
GenServer.call(worker_pid, :message)