partisan_monitor (partisan v6.0.0)
View SourceThis module is responsible for monitoring processes on remote nodes and implementing the monitoring API provided by the partisan module which follows the API provided by the Erlang modules erlang and net_kernel.
YOU SHOULD NEVER USE the functions in this module directly. Use the related functions in partisan instead.
NOTICE
At the moment this only works for
partisan_pluggable_peer_service_managerbackend.Also, certain partisan_peer_service_manager implementations might not support the
partisan_peer_service_manager:on_up/2andpartisan_peer_service_manager:on_down/2callbacks which we need for node monitoring, so in those cases this module will not work.
Summary
Functions
Remove a monitor previously installed by monitor/2. Returns true if the monitor was active and false if it had already fired or was already removed (matching erlang:demonitor/2).
Monitor a remote process. Returns a partisan monitor reference that can be passed to demonitor/2.
Monitor the status of the node Node. If Flag is true, monitoring is turned on. If Flag is false, monitoring is turned off.
Subscribe (or unsubscribe) the calling process to node status change messages. While subscribed, a {nodeup, Node} message is delivered when a new node is connected and a {nodedown, Node} message is delivered when a node is disconnected. If nodedown_reason is in Opts the extended forms {nodeup, Node, InfoList} / {nodedown, Node, InfoList} are delivered instead.
Starts the partisan_monitor server.
Types
-type node_type_mon_opts() :: {Type :: all | visible | hidden, InclReason :: boolean()}.
-type proc_mon_in() :: #partisan_proc_mon_in{ref :: reference(), monitored :: pid() | atom(), monitor :: partisan:remote_pid() | partisan:remote_name(), channel :: partisan:channel()}.
-type proc_mon_in_idx() :: {{node(), partisan:channel()}, reference()}.
-type proc_mon_out_idx() :: {{node(), partisan:channel()}, partisan:remote_reference()}.
Functions
-spec demonitor(MonitoredRef :: partisan:remote_reference(), Opts :: [partisan:demonitor_opt()]) -> boolean() | no_return().
Remove a monitor previously installed by monitor/2. Returns true if the monitor was active and false if it had already fired or was already removed (matching erlang:demonitor/2).
Cleanup happens in two steps: the local bookkeeping (proc_mon_out) is removed synchronously, then a demonitor RPC is sent to the remote partisan_monitor server on the monitored node so it can drop its native monitor and forget the request. If that remote call fails because the peer is unreachable (noconnection, timeout, noproc, nodedown) the function returns true — we assume the remote side has already cleaned up and any in-flight DOWN will be either discarded by the transport or matched against a no-longer-active reference.
Options
flush- If a
DOWNfor this reference is currently in the calling process's mailbox, remove it. The flush is a best-effort localreceive ... after 0— partisan does not provide disterl's exact same-connection barrier, so aDOWNthat has not yet been appended to the mailbox cannot be flushed. Pair with{channel, _}on the originalmonitor/2call to keep theDOWNon the same connection as user traffic and minimise the window where flush can miss.
Failure
notalive- The partisan_monitor server is not running.
not_implemented- The active partisan peer service manager does not support the capabilities required for monitoring.
badargMonitoredRefis not a partisan remote reference, orOptscontains a malformed option.
-spec monitor(Process :: partisan:remote_pid() | partisan:remote_name(), Opts :: [partisan:monitor_opt()]) -> partisan:remote_reference() | no_return().
Monitor a remote process. Returns a partisan monitor reference that can be passed to demonitor/2.
Unlike erlang:monitor/2, delivery of the DOWN signal is best-effort: the signal can be lost on transport disconnection, message loss, or peer-service tree reconfiguration. In those cases the monitor server will fabricate a DOWN with reason noconnection as soon as the disconnection is detected.
Channel binding
A monitor is bound to a single channel for its whole lifetime — by default the partisan default channel, or the channel passed in {channel, Channel}. The channel binding has two effects:
- The eventual
DOWNsignal travels over the same partisan connection as user traffic onChannel, so it is FIFO-ordered with any messages the monitored process sent on that channel before terminating — matching the disterl guarantee that messages from a dying process are delivered before itsDOWN. - If
Channelgoes down (even while other channels to the same node remain up), the monitor fires aDOWNwith reasonnoconnection. This is partisan-specific behaviour — disterl has a single connection per pair of nodes and therefore no per-channel concept.
Options
{channel, Channel}- The channel to bind the monitor to. Defaults to the partisan default channel.
{channel_fallback, boolean()}- If the requested channel is not connected at monitor establishment, whether to fall back to the default channel for the establishment RPC. Defaults to
truewhenChannelis the default channel andfalseotherwise — the explicit-channel default avoids silently splitting the user's traffic and theDOWNsignal across two connections, which would break the FIFO guarantee above.
Failure
notalive- The partisan_monitor server is not running.
not_implemented- The active partisan peer service manager does not support the capabilities required for monitoring.
badargProcessis not a valid partisan remote pid or registered-name reference, orOptscontains a malformed option.
-spec monitor_node(node() | partisan:node_spec(), boolean()) -> true.
Monitor the status of the node Node. If Flag is true, monitoring is turned on. If Flag is false, monitoring is turned off.
Making several calls to monitor_node(Node, true) for the same Node is not an error; it results in as many independent monitoring instances as the number of different calling processes i.e. If a process has made two calls to monitor_node(Node, true) and Node terminates, only one nodedown message is delivered to the process (this differs from erlang:monitor_node/2).
If Node fails or does not exist, the message {nodedown, Node} is delivered to the calling process. If there is no connection to Node, a nodedown message is delivered. As a result when using a membership strategy that uses a partial view, you cannot monitor nodes that are not members of the view.
Failure:
notaliveif the partisan_monitor process is not alive.not_implementedif the partisan peer service manager does not support the required capabilities required for monitoring.badargif any of the arguments is invalid.
This function is executed in the calling process.
-spec monitor_nodes(Flag :: boolean(), [partisan:monitor_nodes_opt()]) -> ok | error | {error, notalive | not_implemented | badarg}.
Subscribe (or unsubscribe) the calling process to node status change messages. While subscribed, a {nodeup, Node} message is delivered when a new node is connected and a {nodedown, Node} message is delivered when a node is disconnected. If nodedown_reason is in Opts the extended forms {nodeup, Node, InfoList} / {nodedown, Node, InfoList} are delivered instead.
If Flag is true a new subscription is started. If Flag is false all subscriptions previously started with the same Opts are stopped. Two option lists are considered equivalent if they contain the same set of options.
Ordering with respect to disterl
Partisan delivers these signals in line with the disterl guarantees, with one important caveat:
nodeupis fired before any message can flow over the newly-established connection (the receiver-process for the new connection is started after the up callbacks run).nodedownis fired only after every message already received on the dying connection has been placed in its destination process's mailbox. The receiver process delivers messages synchronously (erlang:send) and only then exits, and the down callbacks run inline in the manager's exit handler, so the runtime serialises these naturally.- Caveat: a partisan node-pair can have multiple channels.
{nodeup, Node}/{nodedown, Node}fire when the first/last channel is up/down, but a process monitoring on a specific non-default channel may see its monitor'sDOWNbefore the node-levelnodedown(because that channel went down while the node remained reachable on others). For per-channel correctness usemonitor/2with{channel, _}.
Options
{node_type, all | visible | hidden}- Filter the subscription.
hiddenis a no-op since partisan does not have hidden nodes. Defaults toall. nodedown_reason- Deliver the extended 3-tuple form with a reason in the
InfoList.
This function is executed in the calling process.
Starts the partisan_monitor server.
There is one partisan_monitor server instance per node.