Crate mz_dyncfg

source ·
Expand description

Dynamically updatable configuration.

Basic usage:

  • A type-safe static Config is defined near where it is used.
  • Once in the lifetime of a process, all interesting Configs are registered to a ConfigSet. The values within a ConfigSet are shared, though multiple ConfigSets may be created and each are completely independent (i.e. one in each unit test).
  • A ConfigSet is plumbed around as necessary and may be used to get or set the value of Config.
const FOO: Config<bool> = Config::new("foo", false, "description of foo");
fn bar(cfg: &ConfigSet) {
    assert_eq!(FOO.get(&cfg), false);
fn main() {
    let cfg = ConfigSet::default().add(&FOO);

§Design considerations for this library

  • The primary motivation is minimal boilerplate. Runtime dynamic configuration is one of the most powerful tools we have to quickly react to incidents, etc in production. Adding and using them should be easy enough that engineers feel empowered to use them generously.

    The theoretical minimum boilerplate is 1) declare a config and 2) use a config to get/set the value. These could be combined into one step if (2) were based on global state, but that doesn’t play well with testing. So instead we accomplish (2) by constructing a shared bag of config values in each fn main, amortizing the cost by plumbing it once to each component (not once per config).

  • Config definitions are kept next to the usage. The common case is that a config is used in only one place and this makes it easy to see the associated documentation at the usage site. Configs that are used in multiple places may be defined in some common place as appropriate.

  • Everything is type-safe.

  • Secondarily: set up the ability to get and use the latest values of configs in tooling like persistcli and stash debug. As we’ve embraced dynamic configuration, we’ve ended up in a situation where it’s stressful to run the read-write persistcli admin tooling with the defaults compiled into code, but persistcli doesn’t have access to the vars stuff and doesn’t want to instantiate a catalog impl.




  • A type-erased configuration value for when set of different types are stored in a collection.
  • An atomic version of ConfigVal to allow configuration values to be shared between configuration writers and readers.