Beethoven (Beethoven v0.3.9)
A Decentralized failover and peer-to-peer node finding framework for Elixir. Using a TCP socket, Elixir nodes running Beethoven can find each other within a pre-defined network range.
Public API
ready?/0
-> Returns true if Beethoven has fully initialized. False if not. Fully initialized is determined when the RoleMgmt Assigns server.until_ready/1
-> Holds the thread until Beethoven has fully initialized, or provided timeout value has become exhausted. Default timeout value is5_000
milliseconds.get_node_status/0
-> Returns the status of the node within the Beethoven cluster. Possible returns are::standalone
&:clustered
.get_cluster_nodes/0
-> Returns a list of all the nodes have have joined the Beethoven cluster.get_active_cluster_nodes/0
-> Similar toget_cluster_nodes/0
, but only provides nodes that are active/online.get_detailed_cluster_nodes/0
-> Detailed list of all the nodes that have joined the Beethoven cluster + associated metadata.get_roles/0
-> Returns all Beethoven hosted roles with their associated metadata.whois_hosting/0
-> Looks up, and returns a list of nodes that host a given Beethoven role.allocate/0
-> Wrapper forBeethoven.Allocator.allocate/0
.
Architecture
Beethoven is made of multiple smaller services that provide a depth of failover and loadbalancing functionality.
CoreServer
Monitors nodes in the Mnesia cluster.
The server provides a behaviour that allows for PIDs to request a callback in the event of a node status change.
The callback is called alert_me/0
. This function is available to any module using CoreServer
.
Once used, the caller will be sent a GenServer cast containing the updated information.
{:node_update, {nodeName, status}}
Where status can be :offline
or :online
, and nodeName is the URI of the node.
CoreServer manages the monitoring and de-monitoring nodes in Beethoven as they go through their lifecycle.
RoleMgmt
A framework for distributing work across a Beethoven cluster.
Roles are defined in the :beethoven
application configuration.
These roles are hosted on the nodes that come into the cluster, and redistributed when they fail.
For more information on using RoleMgmt, please see the module's documentation.
Allocator
A signal based work allocator that helps determine how busy a given Beethoven cluster node is. Using these signals, it determines how busy a node is, and assigns a float. The smaller the float, the less busy a node is considered.
Using Beethoven.Allocator.Agent
, you gain access to the signal()
macro.
signal(name: :http_connections, weight: 10.0, type: :count)
This allows you to create your own signals to feed into the allocator. This method allows the allocator to be flexible, and signals to be declared and used as needed.
Calling Beethoven.Allocator.allocate/0
will check the Mnesia table used by the Allocator, and return the lest-busy node.
BeaconServer
This PID runs a TCP-Socket server to help new Beethoven nodes find each other.
The port for listener can be set in the application configuration for Beethoven
.
Using this port, the Locator
service within the other nodes can attempt to find each other.
This module utilizes Beethoven.SeekChat
for (de)serialization of TCP calls.
Locator
This PID will enumerate all IPs within a given subnet; checking if they are running an instance of BeaconServer
.
This PID will enumerate the IPs 3 times.
If nothing is found after the 3rd attempt, the cluster start as-is in :standalone mode.
This module utilizes Beethoven.SeekChat
for (de)serialization of TCP calls.
HwMon
Set of PIDs to monitor and record historical hardware consumption.
Will sample CPU and RAM usage every 5 seconds and save up to 100k samples per metric.
When resources are sampled, a signal to Allocator
is called and the utilization is logged.
Summary
Types
List of node names.
Status of a Beethoven cluster node.
List of nodeStatus()
objects.
Role data structure.
List of role()
.
Functions
Returns the least-busy node from the Allocator's Mnesia table.
Returns all active cluster nodes by their Node URI.
Returns the Node URIs of all nodes that have joined the Beethoven Cluster
Returns all cluster nodes and their state.
Returns state of this node within the Beethoven cluster.
Return will only be :clustered
or :standalone
.
Returns all Beethoven hosted roles with their associated metadata.
Gets the current ready state for Beethoven.
Similar to ready?()
but will block until the service is ready.
Defaults to 5_000 milliseconds.
Returns what nodes host a given role.
Types
@type nodeList() :: [node()]
List of node names.
@type nodeStatusMap() :: %{ node: node(), status: Beethoven.CoreServer.nodeStatus(), last_change: DateTime.t() }
Status of a Beethoven cluster node.
@type nodeStatusMapList() :: [nodeStatusMap()]
List of nodeStatus()
objects.
@type role_definition() :: %{ role: atom(), count: integer(), assigned: integer(), nodes: nodeList() }
Role data structure.
@type roleDefinitionList() :: [role_definition()]
List of role()
.
Functions
@spec allocate() :: node()
Returns the least-busy node from the Allocator's Mnesia table.
Wrapper for Beethoven.Allocator.allocate/0
.
@spec get_active_cluster_nodes() :: nodeList()
Returns all active cluster nodes by their Node URI.
@spec get_cluster_nodes() :: nodeList()
Returns the Node URIs of all nodes that have joined the Beethoven Cluster
@spec get_detailed_cluster_nodes() :: nodeStatusMapList()
Returns all cluster nodes and their state.
Example
[%{node: node(), status: :online | :offline, last_change: DateTime.t()}]
@spec get_node_status() :: Beethoven.CoreServer.serverStatus()
Returns state of this node within the Beethoven cluster.
Return will only be :clustered
or :standalone
.
Wrapper for Beethoven.CoreServer.get_mode/0
.
@spec get_roles() :: roleDefinitionList()
Returns all Beethoven hosted roles with their associated metadata.
@spec ready?() :: boolean()
Gets the current ready state for Beethoven.
Wrapper for Beethoven.Ready.ready?/0
.
@spec until_ready(integer()) :: :ok | :timeout
Similar to ready?()
but will block until the service is ready.
Defaults to 5_000 milliseconds.
Wrapper for Beethoven.Ready.until_ready/1
.
Returns what nodes host a given role.