Refactor: extract shared service infrastructure (config, startup, shutdown) #123
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
All three implemented Rust services (audit, secrets, memory) duplicate the same structural patterns:
Config loading — Each service has an identical
Config::load()method:Files:
services/audit/src/config.rs:54-63,services/secrets/src/config.rs:51-59,services/memory/src/config.rs:184-193listen_addr()method — Identicalformat!("{}:{}", self.host, self.port)in all three configs.shutdown_signal()function — Identical async function in all threemain.rsfiles.Tracing initialization — Same
tracing_subscriber::fmt().with_env_filter(...)boilerplate in all threemain.rsfiles.Config environment variable pattern — Same
std::env::var("SERVICE_CONFIG").ok()pattern.Where
services/audit/src/config.rs,services/audit/src/main.rsservices/secrets/src/config.rs,services/secrets/src/main.rsservices/memory/src/config.rs,services/memory/src/main.rsImpact
As more services are added (Model Gateway, Tool Broker), this duplication will grow. Bug fixes or improvements (e.g., adding SIGHUP reload, config validation, graceful drain) would need to be applied in every service.
Suggested approach
Create a
services/commonworkspace crate (e.g.,llm-multiverse-common) containing:ServiceConfigtrait withload()andlisten_addr()default implementationsshutdown_signal()utility functioninit_tracing(service_name: &str)helperserve()helper that combines Server::builder + shutdown signalEach service would depend on this crate and delegate to it, keeping service-specific config fields in their own structs.
🤖 Generated by refactor-review agent
3rd review update: This issue now affects 5 Rust services (up from 3 when filed):
Config::load()listen_addr()shutdown_signal()with_audit_client()builderThe audit client wiring pattern (connect-if-configured with warn-on-failure) is now copied identically in 4 service
main.rsfiles. This compounds the case for a shared crate.Priority should increase given the expanded surface area.
Implemented in PR #225. Created
services/common(llm-common) crate withServiceConfigtrait providing defaultload()andlisten_addr()methods, plus sharedshutdown_signal(),init_tracing(), andconfig_path_from_env()functions. All 5 Rust services now use the shared crate, removing ~100 lines of duplicated boilerplate. Dockerfile template updated to include the new crate.