Current section
Files
Jump to
Current section
Files
lib/zen_monitor/local/tables.ex
defmodule ZenMonitor.Local.Tables do
@moduledoc """
`ZenMonitor.Local.Tables` owns tables that are shared between multiple `ZenMonitor.Local`
components.
See `nodes/0` and `references/0` for more information.
"""
use GenServer
@node_table Module.concat(__MODULE__, "Nodes")
@reference_table Module.concat(__MODULE__, "References")
## Client
def start_link(_opts \\ []) do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
@doc """
Nodes holds cached information about remote node compatibility
This information is stored in one of the following structures:
For compatible nodes
{ remote_node, :compatible }
^---key---^ ^--value--^
For incompatible nodes
{ remote_node, {:incompatible, enforce_until, attempts} }
^---key---^ ^---------------value-----------------^
`enforce_until` is the time (as reported by System.monotonic_time(:milliseconds)) after which
this cache entry should no longer be enforced.
`attempts` is the number of consecutive connect attempts that have failed, this value is useful
for calculating geometric backoff values
"""
@spec nodes() :: :ets.tab()
def nodes do
@node_table
end
@doc """
References holds the set of authoritative monitor references
These references are stored in this structure:
{ {subscriber_pid, monitor_reference}, {remote_node, remote_pid} }
^-------------key-----------------^ ^----------value--------^
There is a compound key of {subscriber_pid, monitor_reference} this allows for lookup of a given
reference (if the subscriber is known, by convention it will be the calling process, self()) or
the retrieval of all active monitors for a subscriber.
"""
@spec references() :: :ets.tab()
def references do
@reference_table
end
## Server
def init(_opts) do
@node_table = :ets.new(@node_table, [:public, :named_table, :set, write_concurrency: true])
@reference_table =
:ets.new(@reference_table, [:public, :named_table, :ordered_set, write_concurrency: true])
{:ok, nil}
end
end