ConfigManager

Struct ConfigManager 

Source
pub struct ConfigManager { /* private fields */ }
Expand description

§Lock Ordering Invariant

To prevent deadlock, ALL methods acquiring multiple locks MUST respect this canonical ordering:

1. reload_mutex (coarse-grained serialization)
2. config (fine-grained data access)

CRITICAL: Never hold config write lock while requesting reload_mutex.

§Atomic Operation Ordering

Atomic operations follow happens-before relationships:

set_value() → increment generation → send SaveRequest
    ↓
background_saver receives → read config + generation → write disk

Sequential consistency (Ordering::SeqCst) ensures all threads see generation increments in the same order.

§Concurrent Safety

  • config: RwLock allows multiple concurrent readers, single writer
  • generation: AtomicU64 provides lock-free increment
  • saving: AtomicBool prevents file watcher self-trigger
  • reload_mutex: Serializes reload operations
  • save_sender: UnboundedSender is lock-free

Implementations§

Source§

impl ConfigManager

Source

pub fn new() -> Self

Source

pub async fn init(&self) -> Result<(), McpError>

Initialize configuration from disk and environment variables

§Errors

Returns error if config directory cannot be created or config file cannot be read/written

Source

pub async fn reload(&self) -> Result<(), McpError>

Reload configuration from disk

Re-reads the config file and updates in-memory state. Serialized with mutex to prevent concurrent reloads (Race #3). Uses the same recovery cascade as init() to handle corruption. Environment variable overrides (KODEGEN_ALLOWED_DIRS, KODEGEN_DENIED_DIRS) are preserved and re-applied after loading.

§Errors

Returns error if config file cannot be read or parsed

Source

pub async fn enable_file_watching(&mut self) -> Result<(), McpError>

Enable automatic config file watching

Starts monitoring the config file for changes. When changes are detected (after 1-second debounce), automatically calls reload().

This is optional and should be enabled via CLI flag (e.g., --watch-config).

§Errors

Returns error if file watching cannot be initialized

Source

pub fn get_config(&self) -> ServerConfig

Source

pub fn get_file_read_line_limit(&self) -> usize

Source

pub fn get_file_write_line_limit(&self) -> usize

Source

pub fn get_blocked_commands(&self) -> Vec<String>

Source

pub fn get_fuzzy_search_threshold(&self) -> f64

Source

pub fn get_http_connection_timeout_secs(&self) -> u64

Source

pub fn get_path_validation_timeout_ms(&self) -> u64

Source

pub fn get_value(&self, key: &str) -> Option<ConfigValue>

Source

pub async fn set_value( &self, key: &str, value: ConfigValue, ) -> Result<(), McpError>

Set a configuration value by key

Thread-safe with generation tracking to prevent lost updates. Increments generation counter atomically after modification.

§Errors

Returns error if the key is unknown, value type is invalid, or config cannot be saved

Source

pub async fn set_client_info(&self, client_info: ClientInfo)

Store client information from MCP initialization

Updates in-memory state immediately and queues async save to disk. Disk write errors are logged but not propagated (fire-and-forget pattern). Use get_save_error_count() to check for save failures.

Source

pub fn get_client_info(&self) -> Option<ClientInfo>

Get current client information

Source

pub fn get_client_history(&self) -> Vec<ClientRecord>

Get client connection history

Source

pub fn get_save_error_count() -> usize

Get total count of config save failures since server start

This counter tracks background save failures (disk write errors). Used for observability and monitoring config persistence issues.

Trait Implementations§

Source§

impl Clone for ConfigManager

Source§

fn clone(&self) -> ConfigManager

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for ConfigManager

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more