v0.9.4 — API Maturity #2
jamesgober
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
config-lib v0.9.4 — Deprecation of the dual
Config/EnterpriseConfigsurfaceThe third patch on the road to 1.0. v0.9.4 begins the architectural consolidation called for in Phase 0.9.4 of the roadmap.
EnterpriseConfig,ConfigManager, and theenterprise::directparsing helpers are all marked#[deprecated]and the unifiedConfigAPI gains aConfigOptionsknobs struct for opt-out behavior (read_onlyis wired today;cache_enabledandcache_capacityare reserved for the v0.9.5 caching work). The deprecation is advisory only — every existing call-site continues to compile and run unchanged through the v0.9.x line.The actual data-model merger — folding
EnterpriseConfig's multi-tier cache into aConfig::getthat still returnsOption<&Value>under concurrent reads — lands with v0.9.5's lock-free caching work. Doing the deprecation announcement and the cache rewrite as two separate releases is intentional: the caching architecture decides the borrow semantics of the unifiedConfig::get, and shipping the API merger ahead of that design would either freeze the wrong return type or force a second migration. v0.9.4 sets users up for the v0.9.5 transition cleanly.What is config-lib?
A multi-format configuration library for Rust. One API for TOML, JSON, INI, XML, HCL, NOML, Java Properties, and CONF — with hot reload, environment variable overrides, schema validation, audit logging, and cached reads. Designed to be the configuration layer a production database can depend on without wrapping.
What's new in 0.9.4
ConfigOptions— opt-out behavior knobsThe single biggest forward-looking addition is
ConfigOptions, a#[non_exhaustive]struct that carries the small set of toggles that should not be enabled by default. v0.9.4 wires one of them (read_only) into the existingConfig::set/remove/mergepaths; the other two (cache_enabled,cache_capacity) are accepted today so that v0.9.5's caching work does not require a second API change at every call site.The struct uses the canonical
#[non_exhaustive]+ consuming-builder-methods pattern so new knobs can be added in v0.9.x MINOR releases without breaking SemVer. The default (ConfigOptions::default()) produces the canonical Hive-DB-tuned configuration; the builder methods are zero-cost type-state shifts.EnterpriseConfig,ConfigManager,enterprise::direct::*deprecatedEvery public item in the
enterprisemodule now carries an explicit#[deprecated(since = "0.9.4", note = "...")]attribute. The notes point users at the corresponding unified-Configoperation. The module-level rustdoc opens with a migration table so anyone discovering the deprecation gets a directly-actionable next step.The deprecation is advisory only:
cargo clippy --all-targets --all-features -- -D warnings): internal references to the deprecated items insideenterprise.rs,ConfigManager, the re-exports inlib.rs, and the comparison benchmarks all carry scoped#[allow(deprecated)]annotations with REPS-AUDIT rationale documenting why the suppression is correct.Migration guide (also in
examples/enterprise_demo.rs)EnterpriseConfig)Config+ConfigOptions)EnterpriseConfig::new()Config::new()EnterpriseConfig::from_string(s, fmt)Config::from_string(s, fmt)EnterpriseConfig::from_file(p)Config::from_file(p)cfg.get("k")(ownedValue)cfg.get("k").cloned()(owned), orcfg.get("k")(borrowed&Value)cfg.set("k", v)cfg.set("k", v)cfg.exists("k")cfg.contains_key("k")cfg.keys()(Vec<String>)cfg.keys()(Result<Vec<&str>>)cfg.save()/cfg.save_to(p)cfg.save()/cfg.save_to_file(p)cfg.merge(other)cfg.merge(other)cfg.set_default(k, v)cfg.get(k).and_then(...).unwrap_or(v)(rich defaults table returns in v0.9.5)cfg.cache_stats()Configin v0.9.5.cfg.make_read_only()Config::with_options(ConfigOptions::new().read_only(true))ConfigManagerenterprise::direct::parse_stringconfig_lib::parseenterprise::direct::parse_fileconfig_lib::parse_fileexamples/enterprise_demo.rsrewritten end-to-endThe headline example for the
enterprisemodule is now a model migration. Five demos covering the original feature surface (set/get with nested keys, default-value lookup, read-only mode viaConfigOptions, file load, one-shot string parsing) all useConfigdirectly. The file closes with the migration table reproduced inline so anyone reading the example as a tutorial sees the old → new translation in context.README leads with
ConfigeverywhereThe README's recommendations now lead with
ConfigandConfigOptions. The old Enterprise Caching section is now a Read-only mode and forward-compatible options section withConfigOptions::new().read_only(true)as the modeled pattern, and a clear deprecation banner pointing readers at v0.9.5 for the caching landing. The Default Configuration Settings — Method 2 section was rewritten from theEnterpriseConfig::set_defaultpattern to the simplerget(k).and_then(..).unwrap_or(default)pattern. The troubleshooting tip about cached reads no longer recommendsEnterpriseConfigfor new code.Why the data-model merger isn't in this release
The roadmap's original Phase 0.9.4 scope reads "Implement new unified
Configcombining the best of both". On closer reading the two surfaces are not source-compatible:Config::get(&str) -> Option<&Value>(borrowed)EnterpriseConfig::get(&str) -> Option<Value>(owned clone, returned from behindArc<RwLock<BTreeMap>>)Returning
&Valuerequires the configuration data to live somewhere that yields a stable reference. The lock-free architecture that makes this safe under concurrent reads —ArcSwap<Arc<Value>>for whole-tree swap,DashMapor equivalent for resolved-key caching — is the explicit subject of Phase 0.9.5. Locking the unifiedConfig::getreturn semantics ahead of that design would either:Configsingle-threaded&Valuereturn and lose the cached-multi-thread storyEnterpriseConfighad, orValuereturns and break every existingConfiguser.Neither was acceptable. v0.9.4 therefore delivers everything that is safely shippable today (deprecation surface,
ConfigOptionsfoundation, runnable migration model, exit-criteria-compliant README) and v0.9.5 will deliver the cache-backed unifiedConfig::getthat the architecture demands. The roadmap's Phase 0.9.4 section now explicitly notes this split, and Phase 0.9.5 is annotated as the merger landing point.Breaking changes
None.
This release does not remove any public item, change any method signature, or alter any runtime behavior of code that does not opt into
ConfigOptions::read_only. Addingread_only = truenewly causesConfig::set/remove/mergeto returnErr(Error::general("Configuration is read-only"))— but only on configurations explicitly constructed with that option. Default-constructedConfiginstances behave exactly as in v0.9.3.Every existing call-site against
EnterpriseConfig,ConfigManager, orenterprise::direct::*continues to compile. They emit deprecation warnings; the warnings are advisory and not promoted to errors anywhere in the crate's own CI gate.Verification
All green.
What's next
The remaining path to 1.0:
Arc<RwLock<BTreeMap>>with a lock-free backend (DashMap or ArcSwap-of-HashMap, decided by criterion benchmark). LandConfig::cache_stats(), theConfigOptions::defaultsfield, and theConfig::make_read_only()ergonomic helper. Verify the sub-50ns single-key-cached-get claim across 1-16 threads by committedcriterionbenchmark. Retire the comparison-baselineenterprise_benchmarks.rsonce the new benches are committed.notify-backed file events on Linux/macOS/Windows.cargo-fuzzper parser, one CPU-hour clean each.1.0.0-rc.1cut.Installation
MSRV in 0.9.4: Rust 1.82 (lowering to 1.75 in 0.9.7 alongside NOML/TOML opt-in).
Documentation
Full diff:
v0.9.3...v0.9.4.Changelog:
CHANGELOG.md.This discussion was created from the release v0.9.4 — API Maturity.
Beta Was this translation helpful? Give feedback.
All reactions