parent v0.10.0 Parent View Source

Functions for implementing a parent process.

A parent process has the following properties:

  1. It traps exits.
  2. It tracks its children inside the process dictionary.
  3. Before terminating, it stops its children synchronously, in the reverse startup order.

In most cases the simplest option is to start a parent process using a higher-level abstraction such as Parent.GenServer. In this case you will use a subset of the API from this module to start, stop, and enumerate your children.

If available parent behaviours don't fit your purposes, you can consider building your own behaviour or a concrete process. In this case, the functions of this module will provide the necessary plumbing. To implement a parent process you need to do the following:

  1. Invoke initialize/0 when the process is started.
  2. Use functions such as start_child/1 to work with child processes.
  3. When a message is received, invoke handle_message/1 before handling the message yourself.
  4. If you receive a shutdown exit message from your parent, stop the process.
  5. Before terminating, invoke shutdown_all/1 to stop all the children.
  6. Use :infinity as the shutdown strategy for the parent process, and :supervisor for its type.
  7. If the process is a GenServer, handle supervisor calls (see supervisor_which_children/0 and supervisor_count_children/0).
  8. Implement format_status/2 (see Parent.GenServer for details) where applicable.

If the parent process is powered by a non-interactive code (e.g. Task), make sure to receive messages sent to that process, and handle them properly (see points 3 and 4).

You can take a look at the code of Parent.GenServer for specific details.

Link to this section Summary

Functions

Awaits for the child to terminate.

Returns true if the child process is still running, false otherwise.

Returns the id of a child process with the given pid.

Returns the meta associated with the given child id.

Returns the pid of a child process with the given id.

Returns the list of running child processes.

Should be invoked by the parent process for each incoming message.

Initializes the state of the parent process.

Returns true if the parent state is initialized.

Returns the count of running child processes.

Terminates all running child processes.

Terminates the child.

Starts the child described by the specification.

Should be invoked by the behaviour when handling :count_children GenServer call.

Should be invoked by the behaviour when handling :which_children GenServer call.

Updates the meta of the given child process.

Link to this section Types

Link to this type

child_id()

View Source
child_id() :: term()
Link to this type

child_meta()

View Source
child_meta() :: term()
Link to this type

child_spec()

View Source
child_spec() :: %{
  :id => child_id(),
  :start => start(),
  optional(:modules) => [module()] | :dynamic,
  optional(:type) => :worker | :supervisor,
  optional(:meta) => child_meta(),
  optional(:shutdown) => shutdown(),
  optional(:timeout) => pos_integer() | :infinity
}
Link to this type

handle_message_response()

View Source
handle_message_response() ::
  {:EXIT, pid(), child_id(), child_meta(), reason :: term()} | :ignore
Link to this type

shutdown()

View Source
shutdown() :: non_neg_integer() | :infinity | :brutal_kill

Link to this section Functions

Link to this function

await_child_termination(child_id, timeout)

View Source
await_child_termination(child_id(), non_neg_integer() | :infinity) ::
  {pid(), child_meta(), reason :: term()} | :timeout

Awaits for the child to terminate.

If the function succeeds, handle_child_terminated/5 will not be invoked.

Returns true if the child process is still running, false otherwise.

Note that this function might return true even if the child has terminated. This can happen if the corresponding :EXIT message still hasn't been processed.

Link to this function

child_id(pid)

View Source
child_id(pid()) :: {:ok, child_id()} | :error

Returns the id of a child process with the given pid.

Link to this function

child_meta(id)

View Source
child_meta(child_id()) :: {:ok, child_meta()} | :error

Returns the meta associated with the given child id.

Link to this function

child_pid(id)

View Source
child_pid(child_id()) :: {:ok, pid()} | :error

Returns the pid of a child process with the given id.

Link to this function

children()

View Source
children() :: [child()]

Returns the list of running child processes.

Link to this function

handle_message(message)

View Source
handle_message(term()) :: handle_message_response() | nil

Should be invoked by the parent process for each incoming message.

If the given message is not handled, this function returns nil. In such cases, the client code should perform standard message handling. Otherwise, the message has been handled by the parent, and the client code doesn't shouldn't treat this message as a standard message (e.g. by calling handle_info of the callback module).

However, in some cases, a client might want to do some special processing, so the return value will contain information which might be of interest to the client. Possible values are:

  • {:EXIT, pid, id, child_meta, reason :: term} - a child process has terminated
  • :ignore - Parent handled this message, but there's no useful information to return

Note that you don't need to invoke this function in a Parent.GenServer callback module.

Link to this function

initialize()

View Source
initialize() :: :ok

Initializes the state of the parent process.

This function should be invoked once inside the parent process before other functions from this module are used. If a parent behaviour, such as Parent.GenServer, is used, this function must not be invoked.

Link to this function

initialized?()

View Source
initialized?() :: boolean()

Returns true if the parent state is initialized.

Link to this function

num_children()

View Source
num_children() :: non_neg_integer()

Returns the count of running child processes.

Link to this function

shutdown_all(reason \\ :shutdown)

View Source
shutdown_all(term()) :: :ok

Terminates all running child processes.

Children are terminated synchronously, in the reverse order from the order they have been started in.

Link to this function

shutdown_child(child_id)

View Source
shutdown_child(child_id()) :: :ok

Terminates the child.

This function waits for the child to terminate. In the case of explicit termination, handle_child_terminated/5 will not be invoked.

Link to this function

start_child(child_spec)

View Source
start_child(child_spec() | module() | {module(), term()}) ::
  Supervisor.on_start_child()

Starts the child described by the specification.

Link to this function

supervisor_count_children()

View Source
supervisor_count_children() :: [
  specs: non_neg_integer(),
  active: non_neg_integer(),
  supervisors: non_neg_integer(),
  workers: non_neg_integer()
]

Should be invoked by the behaviour when handling :count_children GenServer call.

See supervisor_which_children/0 for details.

Link to this function

supervisor_which_children()

View Source
supervisor_which_children() :: [
  {term(), pid(), :worker, [module()] | :dynamic}
]

Should be invoked by the behaviour when handling :which_children GenServer call.

You only need to invoke this function if you're implementing a parent process using a behaviour which forwards GenServer call messages to the handle_call callback. In such cases you need to respond to the client with the result of this function. Note that parent behaviours such as Parent.GenServer will do this automatically.

If no translation of GenServer messages is taking place, i.e. if you're handling all messages in their original shape, this function will be invoked through handle_message/1.

Link to this function

update_child_meta(id, updater)

View Source
update_child_meta(child_id(), (child_meta() -> child_meta())) :: :ok | :error

Updates the meta of the given child process.