update to support user expire, timeout, and disconnect

This commit is contained in:
Evan Carroll 2026-01-17 23:47:02 -06:00
parent fe65835f4a
commit 5fcd49e847
16 changed files with 744 additions and 238 deletions

View file

@ -0,0 +1,88 @@
//! Application configuration for chattyness.
//!
//! Provides TOML-based configuration with sensible defaults for WebSocket
//! timeouts and stale member cleanup.
use serde::Deserialize;
use std::path::Path;
use chattyness_error::AppError;
/// Root configuration structure.
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct AppConfig {
/// WebSocket-related configuration.
pub websocket: WebSocketConfig,
/// Stale member cleanup configuration.
pub cleanup: CleanupConfig,
}
/// WebSocket configuration.
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct WebSocketConfig {
/// Timeout for receiving messages from client before considering connection dead (seconds).
pub recv_timeout_secs: u64,
/// Interval for client to send ping to keep connection alive (seconds).
pub client_ping_interval_secs: u64,
}
/// Cleanup configuration for stale instance members.
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct CleanupConfig {
/// Interval for running stale member cleanup job (seconds).
pub reap_interval_secs: u64,
/// Members with no activity for this duration are considered stale (seconds).
pub stale_threshold_secs: u64,
/// Clear all instance_members on server startup (recommended for single-server deployments).
pub clear_on_startup: bool,
}
impl Default for AppConfig {
fn default() -> Self {
Self {
websocket: WebSocketConfig::default(),
cleanup: CleanupConfig::default(),
}
}
}
impl Default for WebSocketConfig {
fn default() -> Self {
Self {
recv_timeout_secs: 45,
client_ping_interval_secs: 30,
}
}
}
impl Default for CleanupConfig {
fn default() -> Self {
Self {
reap_interval_secs: 120,
stale_threshold_secs: 120,
clear_on_startup: true,
}
}
}
impl AppConfig {
/// Load configuration from a TOML file.
///
/// If no path is provided, returns default configuration.
pub fn load(path: Option<&Path>) -> Result<Self, AppError> {
match path {
Some(p) => {
let content = std::fs::read_to_string(p).map_err(|e| {
AppError::Internal(format!("Failed to read config file {:?}: {}", p, e))
})?;
toml::from_str(&content).map_err(|e| {
AppError::Internal(format!("Failed to parse config file {:?}: {}", p, e))
})
}
None => Ok(Self::default()),
}
}
}

View file

@ -1,8 +1,10 @@
//! Shared utilities for chattyness.
//!
//! This crate provides common validation functions and utilities
//! used across the application.
//! This crate provides common validation functions, configuration,
//! and utilities used across the application.
pub mod config;
pub mod validation;
pub use config::*;
pub use validation::*;