View Source ZenMonitor.Local.Connector (ZenMonitor v2.1.0)

ZenMonitor.Local.Connector performs a variety of duties. For every remote that a the local is interested in monitoring processes on there will be a dedicated ZenMonitor.Local.Connector. This collection of Connectors are managed by a GenRegistry registered under the ZenMonitor.Local.Connector atom.

Connecting and Monitoring the remote ZenMonitor.Proxy

Connectors, as their name suggests, connect to the ZenMonitor.Proxy on the remote node that they are responsible for. They do this using standard ERTS Distribution, by invoking the remote Proxy's ping command. A Remote is considered compatible if the ping command returns the :pong atom, otherwise it will be marked incompatible.

Connectors manage their remote node's status in the global node status cache, and provide facilities for efficient querying of remote status, see compatibility/1 and cached_compatibility/1

Batching and Updating the remote ZenMonitor.Proxy

When a local process wishes to monitor a remote process, the Connector will be informed of this fact with a call to monitor/3. The Connector is responsible for maintaining a local record of this monitor for future fan-out and for efficiently batching up these requests to be delivered to the remote ZenMonitor.Proxy.

Fan-out of Dead Summaries

Periodically, the ZenMonitor.Proxy (technically the ZenMonitor.Proxy.Batcher) on the remote node will send a "Dead Summary". This is a message from the remote that informs the Connector of all the processes the Connector has monitored that have gone down since the last summary.

The Connector uses it's local records to generate a batch of down dispatches. These are messages that look identical to the messages provided by Process.monitor/1 when a process goes down. It is sometimes necessary for the original monitoring process to be able to discern whether the :DOWN message originated from ERTS or from ZenMonitor, to aid this, ZenMonitor will wrap the original reason in a tuple of {:zen_monitor, original_reason}.

The fan-out messages are sent to ZenMonitor.Local for eventual delivery via ZenMonitor.Local.Dispatcher, see those modules for more information.

Fan-out of nodedown / ZenMonitor.Proxy down

The Connector is also responsible for monitoring the remote node and dealing with nodedown (or the node becoming incompatible, either due to the ZenMonitor.Proxy crashing or a code change).

If the Connector detects that the remote it is responsible for is down or no longer compatible, it will fire every established monitor with {:zen_monitor, :nodedown}. It uses the same mechanism as for Dead Summaries, see ZenMonitor.Local and ZenMonitor.Local.Dispatcher for more information.

Link to this section Summary

Functions

Check the cached compatibility status for a remote node

Returns a specification to start this module under a supervisor.

Gets the chunk size from the Application Environment

Puts the chunk size into the Application Environment

Determine the effective compatibility of a remote node

Connect to the provided remote

Asynchronously demonitors a pid.

Get a connector from the registry by destination

Get a connector from the registry by remote node

Callback implementation for GenServer.init/1.

Asynchronously monitors a pid.

Retrieves all the monitors established between the target and the subscriber

Gets the sweep interval from the Application Environment

Puts the sweep interval into the Application Environment

Link to this section Types

Link to this type

cached_compatibility()

View Source

Specs

cached_compatibility() ::
  compatibility() | :miss | {:expired, integer()} | :unavailable

Specs

compatibility() :: :compatible | :incompatible

Specs

death_certificate() :: {pid(), reason :: any()}

Specs

down_dispatch() ::
  {pid(), {:DOWN, reference(), :process, pid(), {:zen_monitor, any()}}}

Specs

t() :: ZenMonitor.Local.Connector

Link to this section Functions

Link to this function

cached_compatibility(remote)

View Source

Specs

cached_compatibility(remote :: node()) :: cached_compatibility()

Check the cached compatibility status for a remote node

This will only perform a fast client-side lookup in the ETS table. If an authoritative entry is found it will be returned (either :compatible, :incompatible, or :unavailable). If no entry is found then :miss is returned. If an expired entry is found then {:expired, attempts} is returned.

Returns a specification to start this module under a supervisor.

See Supervisor.

Specs

chunk_size() :: integer()

Gets the chunk size from the Application Environment

The chunk size is the maximum number of subscriptions that will be sent during each sweep, see ZenMonitor.Local.Connector's @chunk_size for the default value

This can be controlled at boot and runtime with the {:zen_monitor, :connector_chunk_size} setting, see ZenMonitor.Local.Connector.chunk_size/1 for runtime convenience functionality.

Specs

chunk_size(value :: integer()) :: :ok

Puts the chunk size into the Application Environment

This is a simple convenience function for overwriting the {:zen_monitor, :connector_chunk_size} setting at runtime.

Specs

compatibility(remote :: node()) :: compatibility()

Determine the effective compatibility of a remote node

This will attempt a fast client-side lookup in the ETS table. Only a positive :compatible record will result in :compatible, otherwise the effective compatibility is :incompatible

Specs

connect(remote :: node()) :: compatibility()

Connect to the provided remote

This function will not consult the cache before calling into the GenServer, the GenServer will consult with the cache before attempting to connect, this allows for many callers to connect with the server guaranteeing that only one attempt will actually perform network work.

If the compatibility of a remote host is needed instead, callers should use the compatibility/1 or cached_compatibility/1 functions. compatibility/1 will provide the effective compatibility, cached_compatibility/1 is mainly used internally but can provide more detailed information about the cache status of the remote. Neither of these methods, compatibility/1 nor cached_compatibility/1, will perform network work or call into the GenServer.

Specs

demonitor(target :: ZenMonitor.destination(), ref :: reference()) :: :ok

Asynchronously demonitors a pid.

Specs

get(target :: ZenMonitor.destination()) :: pid()

Get a connector from the registry by destination

Specs

get_for_node(remote :: node()) :: pid()

Get a connector from the registry by remote node

Callback implementation for GenServer.init/1.

Link to this function

monitor(target, ref, subscriber)

View Source

Specs

monitor(
  target :: ZenMonitor.destination(),
  ref :: reference(),
  subscriber :: pid()
) :: :ok

Asynchronously monitors a pid.

Link to this function

monitors(target, subscriber)

View Source

Specs

monitors(target :: ZenMonitor.destination(), subscriber :: pid()) :: [
  reference()
]

Retrieves all the monitors established between the target and the subscriber

Specs

sweep_interval() :: integer()

Gets the sweep interval from the Application Environment

The sweep interval is the number of milliseconds to wait between sweeps, see ZenMonitor.Local.Connector's @sweep_interval for the default value

This can be controlled at boot and runtime with the {:zen_monitor, :connector_sweep_interval} setting, see ZenMonitor.Local.Connector.sweep_interval/1 for runtime convenience functionality.

Specs

sweep_interval(value :: integer()) :: :ok

Puts the sweep interval into the Application Environment

This is a simple convenience function for overwriting the {:zen_monitor, :connector_sweep_interval} setting at runtime.