View Source ProcessHub (ProcessHub v0.4.0-beta)
This is the main public API module for the ProcessHub
library. It is recommended to use
only the functions defined in this module to interact with the ProcessHub
library.
ProcessHub is a library that distributes processes within the BEAM cluster. It is designed to be used as a building block for distributed applications that require process distribution and synchronization across multiple nodes.
Summary
Types
The child_id
defines the name of the child. It is used to identify the child.
Each child must have a unique child_id()
in the cluster. A single child may have
multiple pid()
s across the cluster.
Defines the metadata that can be passed to the child process when it is started.
The child_spec
defines the specification of a child process.
The hub_id
defines the name of the hub. It is used to identify the hub.
The init_opts()
defines the options that can be passed to the start_children/3
, start_child/3
,
stop_children/3
, and stop_child/3
functions.
The reply_to
defines the pid()
s that will receive the response from the hub
when a child is started or stopped.
Defines the failure result for a single child start operation.
Defines the success result for a single child start operation.
Defines the failure result for a single child stop operation.
The stop_opts()
defines the options that can be passed to the stop_children/3
and stop_child/3
functions.
Defines the success result for a single child stop operation.
This is the base configuration structure for the hub and has to be passed to the start_link/1
function.
Functions
This function can be used to wait for the ProcessHub
child start or stop
functions to complete.
Dynamically removes previously registered hook handlers for specific hub events.
Returns detailed information about a specific child process registered with the given child_id/0
.
Returns the child specification for the ProcessHub.Initializer
supervisor.
Returns the first available process ID (PID) for a specific child process.
Returns all process IDs (PIDs) for a specific child process.
Checks if a ProcessHub
instance with the given hub_id/0
is currently alive and operational.
Checks if the ProcessHub
with the given hub_id/0
is locked.
Checks if a ProcessHub
instance with the given hub_id/0
is currently in a network-partitioned state.
Returns a list of all nodes where a ProcessHub
instance with the given hub_id/0
is currently running.
Returns a list of all registered processes in the hub.
Returns all information stored in the process registry.
Promotes a ProcessHub
instance to run in distributed node mode.
Dynamically registers hook handlers for specific hub events.
Dumps all information currently stored in the process registry.
Starts a single child process that will be distributed across the cluster based on the configured distribution strategy.
Starts multiple child processes that will be distributed across the cluster.
Starts a new ProcessHub
instance with the specified configuration.
Gracefully stops a running ProcessHub
instance.
Stops a single child process across the entire cluster.
Stops multiple child processes across the entire cluster.
Returns all processes that are registered with a specific tag.
Returns information about child processes in a format similar to Supervisor.which_children/1
,
but wraps the result in a tuple containing the node name and the children.
Types
The child_id
defines the name of the child. It is used to identify the child.
Each child must have a unique child_id()
in the cluster. A single child may have
multiple pid()
s across the cluster.
@type child_metadata() :: %{tag: String.t()}
Defines the metadata that can be passed to the child process when it is started.
@type child_spec() :: Supervisor.child_spec()
The child_spec
defines the specification of a child process.
@type hub_id() :: atom()
The hub_id
defines the name of the hub. It is used to identify the hub.
@type init_opts() :: [ awaitable: boolean(), async_wait: boolean(), timeout: non_neg_integer(), check_existing: boolean(), on_failure: :continue | :rollback, metadata: child_metadata(), disable_logging: boolean(), await_timeout: non_neg_integer() ]
The init_opts()
defines the options that can be passed to the start_children/3
, start_child/3
,
stop_children/3
, and stop_child/3
functions.
:awaitable
- is optional and can be used to specify if the returned value should be an awaitable structProcessHub.Future.t()
. The awaitable struct provides a way to handle the result of the operation synchronously by passing it to theProcessHub.Future.await/1
function.:async_wait
- (deprecated use:awaitable
) is optional and is used to define whether the function should return a function that can be used to wait for the children to start or stop. The default isfalse
.:timeout
- is optional and is used to define the timeout for the function. This timeout option should be used withasync_wait: true
. The default is5000
(5 seconds).:check_existing
- is optional and is used to define whether the function should check if the children are already started. The default istrue
.:on_failure
- is optional and is used to define the action to take when the start operation fails. The default is:continue
which will continue to start the next child. The other option is:rollback
which will stop all the children that have been started.:metadata
- is optional and is used to define the metadata that will be stored in the process registry when the child is started. The metadata can be used to store any information that is needed to identify the child process.:disable_logging
- is optional and is used to define whether logging should be disabled for the child process startup or shutdown. Mostly used for testing purposes.:await_timeout
- is optional and is used to define the maximum lifetime for the spawned collector process. After this time, the collector process will be terminated and attempts to collect the results usingProcessHub.await/1
will fail. The await_timeout option should be used withawaitable: true
. The default is60000
(60 seconds).
@type reply_to() :: [pid()]
The reply_to
defines the pid()
s that will receive the response from the hub
when a child is started or stopped.
Defines the failure result for a single child start operation.
The term()
can be any term that describes the failure reason.
Defines the success result for a single child start operation.
Defines the failure result for a single child stop operation.
The term()
can be any term that describes the failure reason.
@type stop_opts() :: [ awaitable: boolean(), async_wait: boolean(), timeout: non_neg_integer(), await_timeout: non_neg_integer() ]
The stop_opts()
defines the options that can be passed to the stop_children/3
and stop_child/3
functions.
:awaitable
- is optional and can be used to specify if the returned value should be an awaitable structProcessHub.Future.t()
. The awaitable struct provides a way to handle the result of the operation synchronously by passing it to theProcessHub.Future.await/1
function.:async_wait
- (deprecated use:awaitable
) is optional and is used to define whether the function should return a function that can be used to wait for the children to stop. The default isfalse
.:timeout
- is optional and is used to define the maximum time for the function to complete. This timeout option should be used withasync_wait: true
. The default is5000
(5 seconds).:await_timeout
- is optional and is used to define the maximum lifetime for the spawned collector process. After this time, the collector process will be terminated and attempts to collect the results usingProcessHub.await/1
will fail. The await_timeout option should be used withawaitable: true
. The default is60000
(60 seconds).
Defines the success result for a single child stop operation.
@type t() :: %ProcessHub{ child_specs: [child_spec()], deadlock_recovery_timeout: pos_integer(), distribution_strategy: ProcessHub.Strategy.Distribution.ConsistentHashing.t() | ProcessHub.Strategy.Distribution.Guided.t() | ProcessHub.Strategy.Distribution.CentralizedLoadBalancer.t(), dsup_max_restarts: pos_integer(), dsup_max_seconds: pos_integer(), dsup_shutdown_timeout: pos_integer(), hooks: ProcessHub.Service.HookManager.hook_handlers(), hub_id: hub_id(), hubs_discover_interval: pos_integer(), migr_base_timeout: pos_integer(), migration_strategy: ProcessHub.Strategy.Migration.ColdSwap.t() | ProcessHub.Strategy.Migration.HotSwap.t(), partition_tolerance_strategy: ProcessHub.Strategy.PartitionTolerance.Divergence.t() | ProcessHub.Strategy.PartitionTolerance.StaticQuorum.t() | ProcessHub.Strategy.PartitionTolerance.DynamicQuorum.t(), redundancy_strategy: ProcessHub.Strategy.Redundancy.Singularity.t() | ProcessHub.Strategy.Redundancy.Replication.t(), storage_purge_interval: pos_integer(), synchronization_strategy: ProcessHub.Strategy.Synchronization.PubSub.t() | ProcessHub.Strategy.Synchronization.Gossip.t() }
This is the base configuration structure for the hub and has to be passed to the start_link/1
function.
:hub_id
is the name of the hub and is required.:child_specs
is optional and is used to define the child processes that will be started with the hub statically.:hooks
are optional and are used to define the hooks that can be triggered on specific events.:redundancy_strategy
is optional and is used to define the strategy for redundancy. The default isProcessHub.Strategy.Redundancy.Singularity
.:migration_strategy
is optional and is used to define the strategy for migration. The default isProcessHub.Strategy.Migration.ColdSwap
.:synchronization_strategy
is optional and is used to define the strategy for synchronization. The default isProcessHub.Strategy.Synchronization.PubSub
.:partition_tolerance_strategy
is optional and is used to define the strategy for partition tolerance. The default isProcessHub.Strategy.PartitionTolerance.Divergence
.:distribution_strategy
is optional and is used to define the strategy for process distribution. The default isProcessHub.Strategy.Distribution.ConsistentHashing
.:hubs_discover_interval
is optional and is used to define the interval in milliseconds for hubs to start the discovery process. The default is30000
(30 seconds).:deadlock_recovery_timeout
is optional and is used to define the timeout in milliseconds to recover from a locked hub. Hub locking can happen for different reasons such as updating internal data, migrating processes or handling network partitions. The default is60000
(1 minute).:storage_purge_interval
is optional and is used to define the interval in milliseconds for the janitor to clean up the old cache records when the TTL expires. The default is15000
(15 seconds).:migr_base_timeout
is optional and is used to define the base timeout in milliseconds for the migration process to complete before the hub considers it as a failure. The default is15000
(15 seconds).:dsup_max_restarts
is optional and is used to define the maximum number of restarts for the distributed supervisor. SeeSupervisor
child specification for more information. The default is100
.:dsup_max_seconds
is optional and is used to define the maximum number of seconds for the distributed supervisor to restart the child process. SeeSupervisor
child specification for more information. The default is4
.:dsup_shutdown_timeout
is optional and is used to define the timeout in milliseconds for the distributed supervisor to wait before forcefully terminating itself when receiving a shutdown signal.
Functions
@spec await( ProcessHub.Future.t() | {:ok, ProcessHub.Future.t()} | {:error, term()} | term() ) :: {:ok, start_result() | [start_result() | stop_result()]} | {:error, {[start_failure() | stop_failure()], [start_result() | stop_result()]}} | {:error, {[start_failure() | stop_failure()], [start_result() | stop_result()]}, :rollback}
This function can be used to wait for the ProcessHub
child start or stop
functions to complete.
The await/1
function should only be used with the async_wait: true
option.
Keep in mind that the await/1
function will block the calling process until
the response is received. If the response is not received within the timeout
period, the function will return {:error, term()}
.
Example
iex> {:ok, future} = ProcessHub.start_child(:my_hub, child_spec, [async_wait: true])
iex> ProcessHub.await(future)
{:ok, {:my_child, [{:mynode, #PID<0.123.0>}]}}
@spec cancel_hook_handlers(hub_id(), ProcessHub.Service.HookManager.hook_key(), [ ProcessHub.Service.HookManager.handler_id() ]) :: :ok | {:error, term()}
Dynamically removes previously registered hook handlers for specific hub events.
This function allows you to unregister hook handlers that were previously
registered using register_hook_handlers/3
. This is useful for cleanup,
reconfiguration, or when certain handlers are no longer needed.
The function delegates to the coordinator process, which will call the
ProcessHub.Service.HookManager.cancel_handler/3
function for each handler ID.
Parameters:
hub_id
- the hub to remove handlers fromhook_key
- the specific event type (useProcessHub.Constant.Hook
constants)handler_ids
- a list of handler IDs to remove
Examples
iex> ProcessHub.cancel_hook_handlers(
iex> :my_hub,
iex> ProcessHub.Constant.Hook.pre_cluster_join(),
iex> [:my_hook_id, :another_hook_id]
iex> )
:ok
@spec child_lookup(hub_id(), child_id(), [{:with_metadata, boolean()}]) :: {child_spec(), [{node(), pid()}]} | nil
Returns detailed information about a specific child process registered with the given child_id/0
.
This function performs a fast local lookup by querying the local ets
table and does not make
any network calls. The lookup returns the original child specification and location information
for all instances of the process across the cluster.
The return value is a tuple containing the child_spec/0
and a list of {node, pid}
tuples
indicating where the child process is running and its corresponding process ID.
Optionally, you can pass the with_metadata: true
option to include any metadata
that was provided when the child process was started.
Examples
# Lookup a child process by its ID.
iex> {child_spec, node_pids_tuples} = ProcessHub.child_lookup(:my_hub, "child1")
{
%{id: "child1", start: {MyProcess, :start_link, [nil]}},
["node1@127.0.0.1": #PID<0.1487.0>]
}
# Lookup a child process by its ID and include metadata.
iex> {child_spec, node_pid_tuples, metadata} = ProcessHub.child_lookup(:my_hub, "child1", with_metadata: true)
{
%{id: "child1", start: {MyProcess, :start_link, [nil]}},
["node1@127.0.0.1": #PID<0.1487.0>],
%{}
}
@spec child_spec(t()) :: %{ id: ProcessHub, start: {ProcessHub.Initializer, :start_link, [t()]}, type: :supervisor }
Returns the child specification for the ProcessHub.Initializer
supervisor.
This function generates the proper supervisor child specification needed to start a ProcessHub instance under a supervision tree. The returned specification follows the standard Supervisor child_spec format and can be used directly in supervisor child lists.
Examples
iex> ProcessHub.child_spec(%ProcessHub{hub_id: :my_hub})
%{
id: :my_hub,
start: {
ProcessHub.Initializer,
:start_link,
[
%ProcessHub{
hub_id: :my_hub,
child_specs: [],
hooks: %{},
redundancy_strategy: %ProcessHub.Strategy.Redundancy.Singularity{},
migration_strategy: %ProcessHub.Strategy.Migration.ColdSwap{},
synchronization_strategy: %ProcessHub.Strategy.Synchronization.PubSub{
sync_interval: 15000
},
partition_tolerance_strategy: %ProcessHub.Strategy.PartitionTolerance.Divergence{},
distribution_strategy: %ProcessHub.Strategy.Distribution.ConsistentHashing{},
hubs_discover_interval: 10000,
deadlock_recovery_timeout: 60000,
storage_purge_interval: 15000,
migr_base_timeout: 15000,
dsup_max_restarts: 100,
dsup_max_seconds: 4,
dsup_shutdown_timeout: 60000
}
]
},
type: :supervisor
}
Returns the first available process ID (PID) for a specific child process.
This function provides a convenient way to quickly get a PID for a child process. However, when using replication strategies, this function will only return the first available PID, which may not be suitable for all use cases where you need to interact with all replicas.
Replication Warning
When using replication strategies, consider using
get_pids/2
instead to get all PIDs.
Example
iex> ProcessHub.get_pid(:my_hub, :my_child)
#PID<0.123.0>
Returns all process IDs (PIDs) for a specific child process.
This function retrieves all PIDs associated with a given child ID across the cluster. If the child is running on multiple nodes (due to replication), all PIDs will be returned.
Example
iex> ProcessHub.get_pids(:my_hub, :my_child)
[#PID<0.123.0>]
Checks if a ProcessHub
instance with the given hub_id/0
is currently alive and operational.
A hub is considered alive if the ProcessHub.Coordinator
process is
running and the hub is ready to handle requests and manage processes.
Example
iex> ProcessHub.is_alive?(:not_existing)
false
Checks if the ProcessHub
with the given hub_id/0
is locked.
A hub is considered locked if the ProcessHub
local event queue has a priority level
greater than or equal to 10. This is used to throttle the hub from processing
any new events and preserve data integrity.
Example
iex> ProcessHub.is_locked?(:my_hub)
false
Checks if a ProcessHub
instance with the given hub_id/0
is currently in a network-partitioned state.
A hub is considered partitioned when the configured ProcessHub.Strategy.PartitionTolerance
strategy
has detected a network partition event. When a network partition is detected, the hub will
terminate the ProcessHub.DistributedSupervisor
process along with all its managed child processes
to maintain data consistency and prevent split-brain scenarios.
Example
iex> ProcessHub.is_partitioned?(:my_hub)
false
Returns a list of all nodes where a ProcessHub
instance with the given hub_id/0
is currently running.
All nodes running the same ProcessHub
instance (identified by the same hub_id/0
) are considered
to be part of the same logical cluster and can coordinate process distribution and management.
Options:
[:include_local]
- includes the local node in the returned list (default: excludes local node)
Example
iex> ProcessHub.nodes(:my_hub, [:include_local])
[:"node1@127.0.0.1", :"node2@127.0.0.1"]
Returns a list of all registered processes in the hub.
This function provides an efficient way to enumerate all child processes managed by the hub. The returned list contains child IDs and, depending on the scope option, may include node locations and process IDs.
This function performs a fast local query against the ets
table and does not make any network calls.
Available Options:
:global
- returns a list of all child processes across all nodes in the cluster. The return result will be in the format of[{child_id, [{:node, pid}]}]
.:local
- returns only child processes that are running on the local node. The return result will be in the format of[{child_id, [pid]}]
.
Example
iex> ProcessHub.process_list(:my_hub, :global)
[
{:my_child1, [{:node1, #PID<0.123.0>}, {:node2, #PID<2.129.0>}]},
{:my_child2, [{:node1, #PID<0.126.0>}, {:node2, #PID<2.124.0>}]}
]
iex> ProcessHub.process_list(:my_hub, :local)
[{:my_child1, #PID<0.123.0>}]
@spec process_registry(hub_id()) :: ProcessHub.Service.ProcessRegistry.registry()
Returns all information stored in the process registry.
This function performs a local query against the ets
table and does not make any network calls.
Deprecation Notice
This function is deprecated and will be removed in a future version.
Promotes a ProcessHub
instance to run in distributed node mode.
This function should be used when the ProcessHub
was initially started in
non-distributed mode (for example, during development or testing) and you want
to promote it to participate in a distributed cluster.
The promotion process will update all existing child process registrations in the registry to reflect the new node name, ensuring proper cluster coordination.
Parameters:
node_name
(optional) - specifies the node name to use. If not provided, the current node name (Node.self()
) will be used.
@spec register_hook_handlers(hub_id(), ProcessHub.Service.HookManager.hook_key(), [ ProcessHub.Service.HookManager.t() ]) :: :ok | {:error, term()}
Dynamically registers hook handlers for specific hub events.
Hook handlers allow you to execute custom logic when specific events occur within the ProcessHub lifecycle, such as process startup, shutdown, node joining, or cluster events. This provides a powerful extension mechanism for monitoring, logging, or custom business logic.
Parameters:
hub_id
- the hub to register handlers forhook_key
- the specific event type to handle (useProcessHub.Constant.Hook
constants)hook_handlers
- a list ofProcessHub.Service.HookManager
structs defining the handlers
Examples
iex> ProcessHub.register_hook_handlers(
iex> :my_hub,
iex> ProcessHub.Constant.Hook.pre_cluster_join(),
iex> [
iex> %ProcessHub.Service.HookManager{
iex> id: :my_hook_id,
iex> m: SomeModule,
iex> f: :some_function,
iex> a: [:my_first_argument]
iex> }
iex> ]
iex> )
[:ok]
@spec registry_dump(hub_id()) :: ProcessHub.Service.ProcessRegistry.registry_dump()
Dumps all information currently stored in the process registry.
This function returns a comprehensive view of the registry, including child specifications, process IDs, node locations, and metadata for all registered processes. This is useful for debugging, monitoring, or administrative tasks where you need a complete overview of all managed processes in the hub.
Example
iex> ProcessHub.registry_dump(:my_hub)
%{
"child1" => {
%{id: "child1", start: {MyProcess, :start_link, [nil]}},
[
"node1@127.0.0.1": #PID<0.1487.0>
],
%{}
},
"child2" => {
%{id: "child2", start: {MyProcess, :start_link, [nil]}},
[
"node1@127.0.0.1": #PID<0.1488.0>
],
%{}
}
}
@spec start_child(hub_id(), child_spec(), init_opts()) :: {:ok, :start_initiated} | {:ok, ProcessHub.Future.t()} | {:error, :no_children | {:already_started, [atom() | binary(), ...]}}
Starts a single child process that will be distributed across the cluster based on the configured distribution strategy.
The child process will be started on one or more nodes in the cluster depending on the redundancy configuration.
The t:child_spec()
:id
field must be unique across the entire cluster.
Basic Usage
iex> child_spec = %{id: :my_child, start: {MyProcess, :start_link, [nil]}}
iex> ProcessHub.start_child(:my_hub, child_spec)
{:ok, :start_initiated}
By default, the start_child/3
function is asynchronous and returns immediately with a confirmation
that the start operation has been initiated. The actual child process startup happens in the background.
To wait for the child to start and get detailed results, you can pass awaitable: true
to the opts
argument and
use the ProcessHub.Future.await/1
function on the returned future.
See init_opts/0
for all available options including timeout control, failure handling, and metadata.
Synchronous Operation Example
When using the awaitable option, you get detailed information about the startup process including the final status, started processes with their PIDs and node locations, any errors encountered, and rollback information if applicable.
iex> child_spec = %{id: "my_child", start: {MyProcess, :start_link, [nil]}}
iex> future = ProcessHub.start_child(:my_hub, child_spec, [awaitable: true])
{
:ok,
%ProcessHub.Future{
future_resolver: #PID<0.253.0>,
ref: #Reference<0.717952655.487849985.214641>,
timeout: 60000
}
}
# Wait for the child to start and get the result.
iex> ProcessHub.Future.await(future)
%ProcessHub.StartResult{
status: :ok,
started: [{"my_child", ["node2@127.0.0.1": #PID<23618.225.0>]}],
errors: [],
rollback: false
}
# Get the status.
iex> ProcessHub.StartResult.status(result)
:ok
# Get the pid.
iex> ProcessHub.StartResult.pid(result)
#PID<23618.225.0>
Handling startup results
See more about how to handle startup results at Starting and stopping processes
@spec start_children(hub_id(), [child_spec()], init_opts()) :: {:ok, :start_initiated} | {:ok, ProcessHub.Future.t()} | {:error, :no_children | {:error, :children_not_list} | {:already_started, [atom() | binary(), ...]}}
Starts multiple child processes that will be distributed across the cluster.
This function works similarly to start_child/3
, but it handles multiple children simultaneously,
making it much more efficient than calling start_child/3
multiple times. Each child process
will be distributed according to the configured distribution strategy.
All child specifications must have unique :id
fields across the entire cluster.
See init_opts/0
for all available options including failure handling strategies.
Examples
iex> child_specs = [
iex> %{id: "child1", start: {MyProcess, :start_link, [nil]}},
iex> %{id: "child2", start: {MyProcess, :start_link, [nil]}}
iex> ]
iex> # Start the child processes.
iex> future = ProcessHub.start_children(:my_hub, child_specs, [awaitable: true])
{
:ok,
%ProcessHub.Future{
future_resolver: #PID<0.222.0>,
ref: #Reference<0.2401267543.3981705217.217572>,
timeout: 60000
}
}
iex> # Wait for the children to start and get the result.
iex> result = ProcessHub.Future.await(future)
%ProcessHub.StartResult{
status: :ok,
started: [
{"child2", ["node1@127.0.0.1": #PID<0.237.0>]},
{"child1", ["node1@127.0.0.1": #PID<0.236.0>]}
],
errors: [],
rollback: false
}
iex> # Get the pids.
iex> ProcessHub.StartResult.pids(result)
[#PID<0.237.0>, #PID<0.236.0>]
Handling startup results
See more about how to handle startup results at Starting and stopping processes
Warning
Using
start_children/3
withawaitable: true
can lead to timeout errors, especially when the number of children is large.
Starts a new ProcessHub
instance with the specified configuration.
This function initializes a complete ProcessHub system including the coordinator, distributed supervisor, and all necessary supporting processes. The hub will be ready to accept and manage child processes according to the configured strategies.
It is strongly recommended to start the ProcessHub under a supervision tree to ensure proper fault tolerance and automatic restart capabilities.
Example
iex> ProcessHub.start_link(%ProcessHub{hub_id: :my_hub})
{:ok, #PID<0.123.0>}
@spec stop(atom()) :: :ok | {:error, :not_alive}
Gracefully stops a running ProcessHub
instance.
This function will cleanly shut down the ProcessHub system, including terminating all managed child processes and cleaning up associated resources. The shutdown process follows proper OTP shutdown protocols.
Example
iex> ProcessHub.stop(:my_hub)
:ok
@spec stop_child(hub_id(), child_id(), stop_opts()) :: {:ok, :stop_initiated} | {:ok, ProcessHub.Future.t()}
Stops a single child process across the entire cluster.
This function will terminate the specified child process on all nodes where it is currently running. By default, this function is asynchronous and returns immediately with a confirmation that the stop operation has been initiated. The actual process termination happens in the background.
To wait for the child to stop and get detailed results about the termination, you can pass
awaitable: true
in the opts
argument and use the ProcessHub.Future.await/1
function
on the returned future.
Basic Usage
iex> ProcessHub.stop_child(:my_hub, :my_child)
{:ok, :stop_initiated}
See stop_opts/0
for all available options including timeout control.
Example with synchronous wait
iex> ProcessHub.stop_child(:my_hub, "child1", [awaitable: true]) |> ProcessHub.Future.await()
%ProcessHub.StopResult{
status: :ok,
stopped: [{"child1", [:"node1@127.0.0.1"]}],
errors: []
}
Handling stop results
See more about how to handle stop results at Starting and stopping processes
@spec stop_children(hub_id(), [child_id()], stop_opts()) :: {:ok, :stop_initiated} | {:ok, ProcessHub.Future.t()} | {:error, list()}
Stops multiple child processes across the entire cluster.
This function works similarly to stop_child/3
, but handles multiple children simultaneously,
making it much more efficient than calling stop_child/3
multiple times. Each specified
child process will be terminated on all nodes where it is currently running.
See stop_opts/0
for all available options including timeout control.
Examples
iex> ProcessHub.stop_children(:my_hub, ["child1", "child2"], [])
{:ok, :stop_initiated}
Warning
Using
stop_children/3
withawaitable: true
can lead to timeout errors when stopping a large number of child processes.
Handling stop results
See more how to handle stop results at Starting and stopping processes
Returns all processes that are registered with a specific tag.
This function queries the process registry and returns all children that are registered with the given tag. This is particularly useful when you need to group and query processes by category or type using custom tags.
To register a child with a tag, pass the metadata
option to start_child/3
or start_children/3
with a :tag
key containing the desired tag value.
Example
iex> ProcessHub.start_children(:my_hub, child_specs, [metadata: %{tag: "my_tag"}]) |> ProcessHub.Future.await()
iex>
iex> # get the processes by tag name.
iex> ProcessHub.tag_query(:my_hub, "my_tag")
[
{:my_child, [{:mynode, #PID<0.123.0>}],
{:my_child2, [{:mynode2, #PID<0.124.0>}]}
]
@spec which_children(hub_id(), [:global | :local] | nil) :: list() | {node(), [ {any(), :restarting | :undefined | pid(), :supervisor | :worker, :dynamic | list()} ]}
Returns information about child processes in a format similar to Supervisor.which_children/1
,
but wraps the result in a tuple containing the node name and the children.
Performance Warning
The
Supervisor.which_children/1
function is known to consume a lot of memory and can significantly affect performance. This problem is even more relevant when using the:global
option, as it will make network calls to all nodes in the cluster.It is highly recommended to use
ProcessHub.process_list/2
instead, which is more efficient.
Available Options:
:global
- returns a list of all child processes started by all nodes in the cluster. The return result will be in the format of[{:node, children}]
.:local
- returns a list of all child processes started by the local node. The return result will be in the format of{:node, children}
.