pause.gno
2.55 Kb · 63 lines
1package config
2
3import "gno.land/p/moul/pausable/v0"
4
5// The pause switch: one setting that stops every realm reading this one, and
6// one per realm that stops just that one.
7//
8// Set pause "paused: incident, back in an hour"
9// Set pause@r/moul/gns "readonly"
10// Unset pause # running again
11//
12// A realm guards its writes and leaves its reads alone, which is what makes
13// "readonly" the level worth having: the page keeps rendering and explains
14// itself through TopBlock, and nothing new lands.
15//
16// func Post(cur realm, body string) {
17// config.AssertWritable()
18// …
19// }
20//
21// The levels, the fail-closed parse and the stricter-of-two rule all live in
22// gno.land/p/moul/pausable; this file is only the wiring to storage.
23const KeyPause = "pause"
24
25// Pause returns the pause state of the realm calling in: the stricter of the
26// global setting and that realm's own.
27func Pause() pausable.State { return PauseFor(caller()) }
28
29// PauseFor is Pause for a named realm.
30//
31// A stale per-realm entry can never re-open a realm during a global pause,
32// because the two combine with pausable.Strictest rather than one overriding
33// the other. The cost is that exempting one realm from a global pause is not
34// expressible: clear the global and set the others.
35func PauseFor(pkgPath string) pausable.State {
36 global, scoped := scopedPair(KeyPause, pkgPath)
37 return pausable.Strictest(pausable.MustParse(global), pausable.MustParse(scoped))
38}
39
40// IsPaused reports whether the realm calling in is held back at all, ReadOnly
41// as well as fully paused.
42func IsPaused() bool { return Pause().IsPaused() }
43
44// IsPausedFor is IsPaused for a named realm.
45func IsPausedFor(pkgPath string) bool { return PauseFor(pkgPath).IsPaused() }
46
47// AssertWritable aborts unless the realm calling in may still change state.
48// This is the one line a mutating function needs.
49func AssertWritable() { Pause().AssertWritable() }
50
51// AssertWritableFor is AssertWritable for a named realm, for a crossing
52// function that cannot be read off the stack.
53func AssertWritableFor(pkgPath string) { PauseFor(pkgPath).AssertWritable() }
54
55// AssertReadable aborts unless the realm calling in may still be read.
56//
57// Most realms should NOT put this in Render. A page that aborts tells a reader
58// nothing; TopBlock tells them what happened and when to come back. Reach for
59// this only where serving stale data is itself the harm.
60func AssertReadable() { Pause().AssertReadable() }
61
62// AssertReadableFor is AssertReadable for a named realm.
63func AssertReadableFor(pkgPath string) { PauseFor(pkgPath).AssertReadable() }