TwoFaced
Two-phase child process initialization for OTP-compliant processes.
This module provides functionality to start child processes that require two-phase initialization. It is particularly useful when using dynamic supervisors where the child process needs to perform lengthy initialization without blocking the supervisor.
Applications that wish to utilize this functionality should:
- Define their child processes to support a two-phase initialization pattern.
- Parent their child processes under a DynamicSupervisor.
-
Use
TwoFaced.start_child/2,3to start and initialize the child processes.
Handling two-phase initialization means deferring long-running setup tasks via
handle_continue/2 callbacks in GenServer or similar OTP behaviours, and handling
an acknowledgment message (of type ack_request()) to signal completion.
Usage
defmodule MyServer do
use GenServer
@impl GenServer
def init(args) do
{:ok, %{}, {:continue, {:init, args}}}
end
@impl GenServer
def handle_continue({:init, args}, state) do
# Perform lengthy initialization here
:timer.sleep(2000)
{:noreply, state}
end
@impl GenServer
# Acknowledge initialization completion
def handle_info({TwoFaced, :ack, ref}, state) do
TwoFaced.acknowledge(ref)
{:noreply, state}
end
end
{:ok, sup} = DynamicSupervisor.start_link(strategy: :one_for_one)
child_spec = {MyServer, some_arg: :value}
{:ok, pid} = TwoFaced.start_child(sup, child_spec)
true = Process.alive?(pid)Installation
If available in Hex, the package can be installed
by adding two_faced to your list of dependencies in mix.exs:
def deps do
[
{:two_faced, "~> 0.2.2"}
]
endDocumentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/two_faced.