Supervision dispatch module#

The supervision dispatch module provides peer discovery, cooperative lifecycle management, failure detection, and fenced action dispatch across localities, built on top of the supervision module’s lifecycle events and admission checks. See that module’s reference for the semantics of hpx::supervision::check_admission and hpx::supervision::dispatch_outcome; this page documents only the dispatch-specific surface layered on top of them. For the narrative on initialization ordering, one-shot discovery, shadow-state semantics, and client-side filtering versus fenced-dispatch admission, see Supervision dispatch.

Overview#

Functions#

Table 191 hpx::supervision dispatch functions#

Function

Description

hpx::supervision::init

One-shot, idempotent runtime initialization.

hpx::supervision::finalize

One-shot, idempotent runtime teardown.

hpx::supervision::is_initialized

Whether the runtime is currently active.

hpx::supervision::discover_peers

One-time discovery pull across localities.

hpx::supervision::fan_out_join

Fan out join() calls to discovered peers.

hpx::supervision::discover_and_join

Composed discovery-and-join pass.

hpx::supervision::dispatch_work

Dispatch an action under supervision fencing.

Types#

Table 192 hpx::supervision dispatch types#

Type

Description

hpx::supervision::registry

Client handle mirroring a peer’s lifecycle state.

hpx::supervision::server::peer_snapshot

Point-in-time view of a joined peer.

hpx::supervision::discovered_peer

A discovered peer with locality and join epoch.

Lifecycle initialization and shutdown#

hpx::shared_future<hpx::supervision::registry> hpx::supervision::init(hpx::chrono::steady_duration const &discovery_timeout = hpx::supervision::default_discovery_timeout)
hpx::supervision::registry hpx::supervision::init(hpx::launch::sync_policy, hpx::chrono::steady_duration const &discovery_timeout = hpx::supervision::default_discovery_timeout)

Performs one-shot, idempotent initialization of the supervision-dispatch runtime for this locality: creates a local registry, publishes event::started before its symbol name is registered, registers that name, and performs a single discover_and_join() pass. Calling init() while already active is a no-op; concurrent callers during initializing attach to the in-flight operation instead of racing it.

void hpx::supervision::finalize()

Performs one-shot, idempotent teardown of the runtime previously started by init(): publishes event::completed at the current/unchanged epoch, unregisters the registry’s symbol name, and releases the registry. A no-op unless the runtime is currently active.

bool hpx::supervision::is_initialized() noexcept

Returns whether the runtime is currently active. Never blocks; safe to call from any thread, including while init()/finalize() is in flight.

Peer discovery#

struct hpx::supervision::discovered_peer#

A peer whose registry symbol name resolved during a discover_peers() call. Holds locality, registry_client, and join_epoch. discover_peers() leaves join_epoch at hpx::supervision::unjoined_epoch (never 0, which is a legitimate join epoch); fan_out_join() fills it in with the epoch recorded by registry::join(). locality is cached for convenience but is never independently resolved or validated: it is always derived from registry_client itself (see registry::get_locality()), since exactly one registry exists per locality.

std::vector<hpx::supervision::discovered_peer> hpx::supervision::discover_peers(hpx::chrono::steady_duration const &timeout = hpx::supervision::default_discovery_timeout)#

Performs a one-time discovery pull: concurrently resolves the pinned registry name of every remote locality, bounded by a single wait for timeout. Localities that have not yet called init() are silently excluded rather than causing a hang or failure.

std::vector<hpx::supervision::discovered_peer> hpx::supervision::fan_out_join(...)#

Fans out join() calls from local_registry to every entry in peers. Reuses registry::join()’s reservation/idempotency machinery, so repeated or overlapping calls never create more than one shadow per peer locality.

Returns a discovered_peer for each peer whose join() call settled successfully within timeout, in the same relative order as peers. Peers whose join() call did not settle in time are omitted from the result (rather than left as gaps or defaulted entries), so the returned vector is a same-order subset of peers, not index-aligned with it.

std::vector<hpx::supervision::discovered_peer> hpx::supervision::discover_and_join(hpx::supervision::registry const &local_registry, hpx::chrono::steady_duration const &timeout = hpx::supervision::default_discovery_timeout)#

Composes a single reactive discovery-and-join pass: one discover_peers() pull followed by one fan_out_join() call. Introduces no polling, timer, or repeated broadcast of its own.

Returns the same discovered_peer vector produced by fan_out_join() for the peers it discovered.

State query and event publication#

hpx::future<hpx::supervision::lifecycle_state> hpx::supervision::query_state(hpx::supervision::registry const &handle)#
hpx::supervision::lifecycle_state hpx::supervision::query_state(hpx::launch::sync_policy, hpx::supervision::registry const &handle, hpx::error_code &ec = hpx::throws)#
hpx::future<hpx::supervision::lifecycle_state> hpx::supervision::query_state(hpx::supervision::registry const &handle, hpx::supervision::discovered_peer const &peer)#
hpx::supervision::lifecycle_state hpx::supervision::query_state(hpx::launch::sync_policy, hpx::supervision::registry const &handle, hpx::supervision::discovered_peer const &peer, hpx::error_code &ec = hpx::throws)#

The self variants resolve both locality and target to hpx::find_here() and query it on the local locality; the peer variants resolve both locality and target from peer.locality instead - handle is accepted only for overload resolution and symmetry with the self variants, and is otherwise unused in that case. Each overload is a thin forwarder over the corresponding raw-id query_state() overload in Supervision module; see that module’s reference for the fields of the returned lifecycle_state, including the epoch value useful for recovering the epoch a handle’s locality was started at.

hpx::future<hpx::supervision::publish_result> hpx::supervision::publish_event(hpx::supervision::registry const &handle, hpx::supervision::event ev, std::uint64_t epoch = 0)#
hpx::supervision::publish_result hpx::supervision::publish_event(hpx::launch::sync_policy, hpx::supervision::registry const &handle, hpx::supervision::event ev, std::uint64_t epoch = 0, hpx::error_code &ec = hpx::throws)#

Handle-based convenience overloads of hpx::supervision::publish_event that resolve both locality and target to hpx::find_here() instead of requiring the caller to name them explicitly. Thin forwarders over the raw-id publish_event() overloads in Supervision module. There is no peer variant: a locality publishes lifecycle events only for itself, never on behalf of a peer. The default epoch value of 0 is only correct for a locality’s very first publication after init(); once the target’s real epoch has advanced, 0 is stale. Callers publishing events after the initial one should first obtain the current epoch - e.g. via query_state(hpx::launch::sync, handle).epoch - and pass it explicitly.”

Registry client#

class hpx::supervision::registry

A lightweight, self-supervising client handle for pairing with peer localities; mirrors a peer’s lifecycle state locally via join() and can itself be discovered by name in AGAS.

hpx::future<hpx::supervision::joined_peer> join(hpx::id_type const &peer_locality) const#
hpx::supervision::joined_peer join(hpx::launch::sync_policy, hpx::id_type const &peer_locality, hpx::error_code &ec = hpx::throws) const#

Joins a peer locality: creates (or reuses) local supervision state mirroring the peer’s lifecycle. The returned joined_peer::target is peer_locality itself (not a generated local id) and is what dispatch_work() colocates against.

hpx::future<std::vector<hpx::supervision::server::peer_snapshot>> snapshot_peers() const#
std::vector<hpx::supervision::server::peer_snapshot> snapshot_peers(hpx::launch::sync_policy, hpx::error_code &ec = hpx::throws) const#

Returns a point-in-time snapshot of all fully joined, non-evicting peers.

hpx::future<bool> register_name()#
bool register_name(hpx::launch::sync_policy, hpx::error_code &ec = hpx::throws)#
hpx::future<hpx::id_type> unregister_name() const#
hpx::id_type unregister_name(hpx::launch::sync_policy, hpx::error_code &ec = hpx::throws) const#
struct hpx::supervision::server::peer_snapshot

Plain-data view of a single joined peer: peer_locality and join_epoch.

Fenced dispatch#

template<typename Action, typename ...Ts>
decltype(auto) hpx::supervision::dispatch_work(hpx::id_type const &target, std::uint64_t epoch, Ts&&... ts)#

Dispatches Action to target under supervision fencing. Performs a cheap, non-authoritative admission check on the caller’s locality to short-circuit an already-known-fenced target, then dispatches to the target’s own locality (via hpx::colocated) where an authoritative re-check against the same latch consulted by hpx::supervision::check_admission runs immediately before the wrapped action executes, on the same thread, closing the admission/invocation race. See Supervision dispatch for the full client-side-filtering versus fenced-admission narrative and worked examples.

Throws

hpx::exception with hpx::error::target_fenced if the target has latched a terminal event for epoch since the client-side check; the wrapped action is not invoked in that case.

Testing support#

The following are declared in hpx/supervision_dispatch/testing.hpp and are not part of the stable public dispatch API; they exist solely to make unit tests for this module deterministic:

std::vector<hpx::supervision::server::peer_snapshot> hpx::supervision::testing::local_snapshot_peers()
void hpx::supervision::testing::set_failure_detection_poll_timeout_for_testing(hpx::chrono::steady_duration const &timeout)
hpx::id_type hpx::supervision::testing::last_join_locality()
void hpx::supervision::testing::suspend_heartbeat_for_testing()
bool hpx::supervision::testing::failure_detection_sweep_in_flight_for_testing()

See the API reference of this module for more details, and Supervision module for the underlying lifecycle event, admission, and dispatch-outcome semantics this module builds on.