mod.rs
Overview
This file implements the core logic for managing and synchronizing a proxy configuration with an external blockchain proxy list. It provides functionalities to:
Load and monitor proxy configuration files.
Retrieve and compare the current proxy list from the blockchain.
Update the local proxy configuration to match the blockchain data.
Reload the proxy service to apply configuration changes via different methods (Docker container signal, process signal by PID).
It serves as the main runtime entry point for the proxy manager component, orchestrating configuration synchronization and proxy reloading in a continuous loop.
The file depends on several modules and external crates:
clifor command-line argument parsing.blockchainfor fetching proxy lists from the blockchain.ProxyConfigstruct to load/save proxy configuration files.docker_apicrate for Docker container interaction.tokiofor asynchronous runtime support.
Modules
blockchain: Handles blockchain-related logic including fetching the proxy list.cli: Provides command-line parsing structures and enums.
Both modules are imported as submodules and utilized within this file to perform their respective roles.
Constants
CONFIG_CHECK_INTERVAL: Duration— Defines the sleep interval duration (5 seconds) between each configuration check in the proxy manager loop.
Functions
pub fn run() -> Result<(), std::io::Error>
Purpose:
Entry point for starting the proxy manager. This function initializes environment variables, tracing/logging, and spawns the Tokio asynchronous runtime in a separate thread named "tokio_main". It handles any panics or errors from the async runtime and exits the process accordingly.
Parameters:
None.
Returns:
Ok(())if the runtime starts and completes without errors (though it typically exits).Err(std::io::Error) if thread spawning fails.
Usage Example:
fn main() {
if let Err(e) = run() {
eprintln!("Failed to start proxy manager: {}", e);
}
}
async fn tokio_main() -> anyhow::Result<()>
Purpose:
Asynchronous main function that parses CLI arguments and invokes the core proxy manager task. It handles any errors by logging and exiting the process.
Parameters:
None.
Returns:
Ok(())on successful completion.An error wrapped in
anyhow::Resulton failure.
Implementation Details:
Uses
cli::CliArgs::parse()for command-line argument parsing.Calls
proxy_manager(args).awaitto run the proxy management loop.
pub async fn proxy_manager(args: cli::CliArgs) -> anyhow::Result<()>
Purpose:
Main loop function that continuously monitors the proxy list from the blockchain and updates the local proxy configuration file if discrepancies are found. It also triggers proxy reloads to apply updated configurations.
Parameters:
args: cli::CliArgs— Command-line arguments containing configuration file path and reload command.
Returns:
Ok(())if the loop runs without unrecoverable errors.anyhow::Resulterror in case of failures reading configuration, fetching blockchain data, or reloading proxy.
Workflow:
Loads the proxy configuration from the specified file.
Fetches the current proxy list from the blockchain asynchronously.
Converts both proxy lists into
HashSet<SocketAddr>for efficient comparison.Compares the sets for any differences:
If the blockchain proxy list contains addresses not in the configuration's
subscribelist, logs an error and exits.Otherwise, updates the configuration to retain only proxies present in the blockchain list.
Saves the updated configuration file.
Calls
reload_proxyto signal the proxy service to reload.
Sleeps for
CONFIG_CHECK_INTERVALbefore repeating.
Important Implementation Details:
Uses
HashSetdifference operations to detect mismatches.Enforces strict consistency between blockchain proxy list and local credentials.
Uses synchronous
std::thread::sleepinside an async context for simplicity.
Usage Example:
let args = cli::CliArgs::parse();
proxy_manager(args).await?;
async fn reload_proxy(settings: &cli::Command) -> anyhow::Result<()>
Purpose:
Reloads the proxy service based on the specified reload command method.
Parameters:
settings: &cli::Command— Enum specifying the reload strategy:Docker { socket, container }— Sends a SIGHUP signal to a Docker container.PidPath { pid_path }— (Unimplemented) Intended to reload by reading a PID from a file.Pid { pid }— Sends a SIGHUP signal to a process by PID.
Returns:
Ok(())if the reload signal was sent successfully.anyhow::Resulterror if signaling fails or the method is unimplemented.
Implementation Details:
For Docker, uses
docker_apicrate to access the Docker daemon and kill the container with SIGHUP.For PID, invokes system
killcommand with-HUPflag.The PID path method is currently unimplemented and will panic if invoked.
Usage Example:
let cmd = cli::Command::Pid { pid: 1234 };
reload_proxy(&cmd).await?;
Interaction with Other Parts of the System
climodule: Provides CLI argument structs (CliArgs) and command enum (Command) which define configuration file paths and proxy reload methods.ProxyConfigstruct: Used to load, modify, and save proxy configuration files. It is critical for maintaining synchronization with the blockchain proxy list.blockchainmodule: Fetches the authoritative proxy list from the blockchain asynchronously.docker_apicrate: Used for interacting with Docker containers to send signals for reloading.Logging/Tracing: Utilizes
tracingcrate for structured logging throughout the lifecycle.Environment Variables: Loads environment variables using
dotenvyto configure runtime behavior.
Implementation Details and Algorithms
The proxy manager loop implements a periodic polling mechanism (
CONFIG_CHECK_INTERVAL) to maintain configuration consistency.It leverages set operations (
HashSet<SocketAddr>) to perform efficient difference and intersection calculations between the local and blockchain proxy lists.On detecting mismatches, it updates the local config by removing unauthorized subscriptions, ensuring only valid proxies remain.
Proxy reload is signaled by sending
SIGHUPsignals to either Docker containers or processes, triggering them to reload their configurations without downtime.The design ensures that if unauthorized proxies are detected, the program exits immediately to prevent misconfiguration.
Visual Diagram
flowchart TD
A["run()"] --> B[Start tokio_main thread]
B --> C["tokio_main()"]
C --> D[Parse CLI args]
D --> E["proxy_manager(args)"]
E --> F{Infinite Loop}
F --> G[Load ProxyConfig from file]
F --> H[Fetch proxy list from blockchain]
F --> I[Compare proxy sets]
I -->|Mismatch detected| J[Update config subscribe list]
J --> K[Save updated config]
K --> L["reload_proxy(command)"]
L --> M{Reload method?}
M -->|Docker| N[Send SIGHUP to container]
M -->|Pid| O[Send SIGHUP via kill command]
M -->|PidPath| P[Unimplemented panic]
I -->|No mismatch| F
F -->|Sleep 5s| F
This diagram illustrates the primary control flow of the proxy manager from program start to continuous proxy configuration monitoring and reload signaling.