Documentation Index
Fetch the complete documentation index at: https://docs.springtail.io/llms.txt
Use this file to discover all available pages before exploring further.
AdminServer Class
Overview
AdminServer provides an embedded HTTP administration interface for Springtail services.
It runs as a singleton service, starts its own thread, and exposes a small HTTP API for
health checks, configuration inspection, logging control, and dynamically registered
administrative endpoints. The server automatically binds to an available port and publishes its address to Redis for service discovery.
The server is built on top of httplib::Server and uses JSON for all request and response
payloads.
Features
- Embedded HTTP server using the
cpp-httpliblibrary - Dynamic route registration for GET and POST handlers
- Built-in health and configuration endpoints
- Centralized error handling and response formatting with structured JSON responses
- Thread-safe dynamic route management using shared mutexes
- Automatic service discovery via Redis integration
- Logging control through HTTP endpoints
- Single-threaded request processing for simplicity
- Runs in a dedicated thread
- Singleton-based lifecycle management
Lifecycle
The AdminServer instance is created automatically when first accessed. Startup and shutdown are managed through the common Singleton infrastructure. On startup:- The HTTP server thread is started
- Default routes are registered
- The server binds to an IP and port
- The bound address is published to Redis
- The HTTP server is stopped
- The server thread is joined
- Resources are released cleanly
Class Declaration
AdminServer inherits from Singleton<AdminServer> to ensure only one instance exists throughout the application lifetime.
Public Interface
Type Definitions
GetHandler
path: The request pathparams: URL query parametersjson_response: JSON object to populate with response data
PostHandler
path: The request pathparams: URL query parametersbody: Request body as stringjson_response: JSON object to populate with response data
Route Management Methods
register_get_route()
path: The URL path to handle (e.g., “/status”)handler: Handler function to execute for this path
deregister_get_route()
path: The URL path to deregister
register_post_route()
path: The URL path to handlehandler: Handler function to execute for this path
deregister_post_route()
path: The URL path to deregister
exists()
true if instance exists, false otherwise
Built-in Endpoints
The AdminServer provides several built-in endpoints for common administrative tasks:GET /health
Returns server health status. Response:GET /config
Returns all application configuration settings. Response:GET /logging
Returns current logging configuration and statistics. Response:POST /logging
Updates logging configuration dynamically. Request Body:Custom Route Registration
The users of this class may dynamically register and deregister administrative routes.Error Handling
All request handlers are executed inside a common error wrapper that:- Converts exceptions into JSON responses
- Sets appropriate HTTP status codes
- Logs errors consistently
HttpErrorfor application-level HTTP failures- JSON parsing errors
- Standard C++ exceptions
- Unknown exceptions
HttpError Exception
HttpError represents an HTTP-aware exception type.
Features:
- Custom error message
- Explicit HTTP status code
- Automatically translated into JSON error responses
Constructor
msg: Error messageerror_code: HTTP status code (default: 400)
Method
InternalHTTPServer Class
InternalHTTPServer is a private nested class that extends httplib::Server to provide additional functionality.
Capabilities:
- Retrieve bound IP and port at runtime
- Convert HTTP requests into a human-readable string format for debugging
Methods
get_bind_ip_port()
request_to_string() (static)
request: The HTTP request to convert
Private Implementation Details
Constructor
- Configures the HTTP server with a single-threaded task queue
- Registers all built-in endpoints (/health, /config, /logging)
- Sets up wildcard dispatchers for GET and POST requests
- Starts the server thread
- Waits until the server is ready
- Publishes the server address to Redis for service discovery
Thread Management
_internal_run()
_internal_thread_shutdown()
Request Dispatching
_dispatch_get()
- Looks up handler in
_get_routesmap - Invokes handler if found
- Throws
HttpErrorwith 404 status if no handler exists
_dispatch_post()
- Looks up handler in
_post_routesmap - Invokes handler if found
- Throws
HttpErrorwith 404 status if no handler exists
Error Handling
_wrap_error_handler()
HttpError: Returns custom error code with error messagenlohmann::detail::exception: Returns 500 with JSON parsing error detailsstd::exception: Returns 500 with standard exception message...(catch-all): Returns 500 with unknown error status
Member Variables
Redis Integration
On startup, the server publishes its network location to Redis using:- Instance ID
- Instance key
- Program name
Usage
Functionality:- The server listens on 0.0.0.0 by default
- The port is assigned dynamically unless configured otherwise
- All responses are JSON
- Unregistered paths return HTTP 404
Basic Usage Example
Handler with Error Handling
Using Query Parameters
Deregistering Routes
Service Discovery
On startup, the AdminServer automatically publishes its listening address to Redis: Redis Key Format:Thread Safety
- Route registration/deregistration uses
std::unique_lockfor exclusive access - Route dispatching uses
std::shared_lockfor concurrent read access - Multiple GET/POST requests can be processed concurrently (read access)
- Route modifications block all request processing (write access)
- The server uses a single-threaded task queue, so handlers execute sequentially
Design Considerations
- Single-threaded Processing: The server uses a single-threaded task queue to simplify synchronization and avoid complex concurrency issues in handlers
- Dynamic Port Selection: Binding to port 0 allows the OS to select an available port, avoiding conflicts
- Wildcard Matching: The server registers wildcard patterns (
.*) and uses custom dispatchers for flexible routing - JSON-based Communication: All responses are JSON for consistency and ease of parsing
- Centralized Error Handling: The
_wrap_error_handlertemplate ensures consistent error responses across all endpoints
Notes
- The server automatically binds to
0.0.0.0on an available port - All handlers must populate the
json_responseparameter - Throwing
HttpErrorallows custom HTTP status codes - The server waits until ready before publishing to Redis
- Built-in endpoints cannot be deregistered
- Route paths are exact matches (no regex or wildcards in custom routes)