Appearance
The Node
A node is a running instance of the framework. Think of it as the container that holds everything together — the event loop, the listeners, the state, and the mesh connections. You interact with it through framework::app, which creates and manages a node internally.
What a Node Does
- Accepts incoming client connections (HTTP, WebSocket, TCP)
- Connects to other nodes in the mesh
- Runs the event loop that processes all I/O
- Manages graceful startup and shutdown
Starting a Node
Creating a framework::app internally creates and initializes a node:
cpp
#include <framework.hpp>
using namespace framework;
int main() {
framework::app app;
// ... configure routes, handlers, services ...
app.run(); // blocks until SIGINT/SIGTERM
}The node is not a class you instantiate directly — it is created and owned by framework::app.
Node Identity
Every node has a unique UUID assigned at startup. You can access it through the state:
cpp
auto& node_id = app.get_state()->get_id();
// → "a1b2c3d4-... (UUID)"The UUID is generated randomly at each startup and is not persisted across restarts. It is used for node identification within the mesh during a single session.
Note: Since the UUID changes on every restart, the vector clock system will treat a restarted node as a brand-new peer. Cache consistency and conflict resolution are unaffected, but long-lived node references in your application code should use a stable identifier (e.g., hostname) instead of the UUID.
Node Ports
A node can listen on multiple ports, each configured independently:
- Client port (
ports_.client_port_) — serves HTTP, WebSocket, and TCP connections. Default is0(no auto-start). You must callrun_http_service(port),run_websocket_service(port), orrun_tcp_service(port)explicitly to start listeners. - Node port (
ports_.node_port_) — handles inter-node mesh traffic. Default is10000. Used whenrun_mesh()is called.
If you only need HTTP, you only need to configure the client port and call run_http_service(). The node port is only required for mesh networking.
Lifecycle
The node (via app.run()) progresses through these phases:
- Initialization — Configuration is loaded, listeners are created, WAL is initialized. Boot callbacks registered via
on_boot()fire after initialization. - Connection — If seed configuration is set, the node connects to the seed and discovers peers in the mesh.
- Running — The event loop processes connections and messages. Background timers run for metrics collection, gossip failure detection, and Raft consensus heartbeats.
- Shutdown — On
SIGINT,SIGTERM, orapp.stop(), all listeners close, connections drain gracefully, timers are cancelled, and state is flushed.
Connecting to a Specific Node
For advanced mesh topologies, you can connect to a node directly without seed discovery:
cpp
// Available internally in the node implementation
// node.connect_to_node("10.0.0.5", 10001);This is used by the gossip engine and Raft to establish peer connections discovered through the mesh.
Next: The App — the user-friendly interface to the node.