Config / Live settings
Live settings
A setting marked live may change while the program runs, and nothing else
may. A change is kept in the store over every layer until it is reset, so it
survives a restart, and every process that shares the store sees it before
update returns.
const config = await store.config('app', [{ port: 8080, limits: { rps: live(100), burst: live(50) } }])
await config.update({ limits: { rps: 200 } }) // kept; every handle and process sees it
await config.reset('limits.rps') // the layers give it again
await config.reset() // every change of the config@dataclass
class Limits:
rps: int = live(100)
burst: int = live(50)
await config.update({"limits": {"rps": 200}})
await config.reset("limits.rps")
await config.reset()type Limits struct {
RPS int `json:"rps" config:"live"`
Burst int `json:"burst" config:"live"`
}
err = config.Update(ctx, func(s *Settings) { s.Limits.RPS = 200 })
err = config.Reset(ctx, "limits.rps")
err = config.ResetAll(ctx)#[derive(Clone, Serialize, Deserialize, Default)]
#[serde(default)]
struct Limits {
rps: Live<u32>,
burst: Live<u32>,
}
config.update(|s| *s.limits.rps = 200)?;
config.reset("limits.rps")?;
config.reset_all()?;Only what is live changes
config app: port is not live: invalidupdate({ port: 9000 }) is invalid, and TypeScript refuses it as it is
written. Settings that take effect only at start, an address, a path, a pool
size, are never changed under a running program by mistake: mark live only
what the program reads on every use.
A change outranks every layer
A kept change is the strongest layer on purpose: live(100) lets whoever
runs the program, through an admin page of yours, outrank the
code, the files and the environment. A deploy that sets APP_LIMITS_RPS
does not undo it:
path value from over
limits.rps 200 a change, 12 October 14:03, version 7 1000 APP_LIMITS_RPS, 100 the declarationreset removes the change and lets the layers give the setting again.
Two changes, two settings
update keeps the settings it names, and in Go and Rust the ones its function
changed, never the whole value. Two updates of different settings both stay,
from two processes too: { rps: 200 } and { burst: 500 } make
{ rps: 200, burst: 500 }. An update keeps all its settings or none, and the
value they make is validated whole.
Versions
Every change moves the config's version. An admin page that shows a value
sends the version it showed, and an update another change came before is
conflict:
const shown = config.version
// … the admin edits the form …
await config.update({ limits: { rps: 300 } }, { ifVersion: shown }) // ConflictError if someone changed it meanwhileshown = config.version
await config.update({"limits": {"rps": 300}}, if_version=shown)shown := config.Version()
err = config.Update(ctx, func(s *Settings) { s.Limits.RPS = 300 }, tinystore.IfVersion(shown))let shown = config.get().version();
config.if_version(shown).update(|s| *s.limits.rps = 300)?;value and version change together, so what was shown and what is sent
always match.
A change that no longer fits
A deploy can tighten a rule: rps was any number, now at most 500, and 800 is
kept. A kept change that no longer fits, the setting no longer live, now a
secret, of another type or refused by validate, is ignored, not removed:
- the open warns about it in the log, once;
explainlists it with why;- it applies again once it fits, and
resetof its path removes it.
So a stricter release still starts. strict: true fails the open instead,
for a config whose defaults are worse than not starting.
Several programs, one config
Through a server, several programs open one config, each with its own declaration: two versions of one program during a deploy, or a web process and a worker that read different settings. A change is checked against the declaration of every handle open when it comes, and one any of them refuses keeps nothing:
config app: limits.rps: 800 is above 500, as another program that has the config open declaresA kept change of a setting a program does not declare may be another
program's: it is neither applied nor warned about, and explain lists it
apart.
Limits
| What | Limit |
|---|---|
| a setting's value, kept | 16 KiB of JSON |
| what a config keeps of its changes | 256 KiB |
See also
- Config: the engine's overview.
- Watching: applying a change the moment it is made.
- Turn replies off live in the Handbook.