Skip to content

Managed updater: own the silent-check throttle stamp and sticky rollout bucket - #273

Closed
turinglambdaai wants to merge 1 commit into
mainfrom
feat/update-scaffolding
Closed

turinglambdaai wants to merge 1 commit into
mainfrom
feat/update-scaffolding

Conversation

@turinglambdaai

Copy link
Copy Markdown
Owner

Closes #251. Delivers the distribution-side glue of #240.

What

Hosts hand-roll silent-check timestamps in three languages with three write-time semantics (threadly macOS stamps before the check; threadly/taskly Windows stamp even when the transport failed; Linux stamps only when the check settles; movebit has no stamp at all). make-updater now owns the stamp:

  • #:settings-get/#:settings-set! (provided together) parameterize persistence — products keep their own settings store (config file, SQLite, Keychain-backed); the contract is string keys in, values out, durable before settings-set! returns.
  • updater-silent-check! gates the network behind updater-silent-check-due? and writes the stamp under silent-check-stamp-key only after the check settles — an answer or a definitive error result. An outage cannot be retried in a tight loop; an offline launch that is externally interrupted does not buy four silent hours without an actual answer.
  • A failed or unreadable stamp write falls back to a process-lifetime memory stamp, so a broken store cannot defeat the throttle.
  • resolve-rollout-bucket! + draw-rollout-bucket recover the sticky 0–99 rollout bucket from the same interface (OS entropy draw — racket/base's PRNG has a fixed seed), redrawing on corrupt values and degrading to an unpersisted draw when the store cannot persist.

This is #240's backend glue: the update state machine, progress snapshot, deadline watchdog, cancellation, throttle stamp, and bucket persistence now live in one tested module; products keep ~100 lines of glue (config whitelist discipline, host install flows, platform quirks). Product repos migrate on their own schedule; their hand-rolled timestamp code can then be deleted wholesale.

Docs

docs/release-and-updates.md documents the settings contract, the settle-then-stamp semantics, and the rollout helpers; rivet.scrbl gains the five new public exports (public-api expectation and documentation guards updated).

Tests

82 tests in rivet/tests/managed-updater.rkt: due/throttled/settle paths, error-settle stamping, expired stamps, memory fallback with a broken store, interface-required errors, bucket stickiness/corruption/persistence-failure, plus the existing 30 updaters tests.

…managed updater

Hosts hand-roll silent-check timestamps in three languages with three
write-time semantics: threadly macOS stamps before the check (an offline
launch buys four silent hours without an answer), threadly/taskly Windows
stamp even when the transport itself failed, Linux variants stamp only
when the check settles, and movebit never persists a stamp at all.

make-updater now accepts #:settings-get/#:settings-set! (provided
together) and #:silent-throttle-seconds (default four hours). The
stamp lives behind that settings interface under silent-check-stamp-key
(a unix-seconds integer); hosts whose store is string- or symbol-keyed
translate on their side of the boundary. updater-silent-check! gates
the network behind updater-silent-check-due? and stamps only after the
check settles — an answer or a definitive error result — so an outage
cannot be retried in a tight loop and an interrupted launch does not
suppress the next check. A failed or unreadable stamp write falls back
to a process-lifetime memory stamp so a broken store cannot defeat the
throttle.

resolve-rollout-bucket! recovers the sticky 0-99 rollout bucket from the
same settings interface (drawing a fresh one on first run via
draw-rollout-bucket, which uses OS entropy because racket/base's PRNG
has a fixed seed); corrupt stored values redraw, and a store that
cannot persist degrades to an unpersisted draw. Products keep their
config whitelist discipline, host install flows, and platform quirks;
the throttling, bucket persistence, and stamp semantics stop being
per-product code (issue #240's backend glue, issue #251's semantics).
@turinglambdaai

Copy link
Copy Markdown
Owner Author

Closing as a duplicate: #271 (opened earlier today by a parallel session) delivers the same two issues with a dedicated rivet/distribution/updater-scaffold.rkt module — the updater config + destination + settings bridge + phase box that replaces the 109 duplicated product lines (#240) and the settle-then-stamp throttle (#251, identical semantics: stamp written only when a check settles on an answer or definitive failure, read through the product's settings adapter).

My implementation extended the existing managed-updater.rkt instead, which overlaps #271's scope but adds one piece #271 does not currently carry: sticky rollout bucket resolution (resolve-rollout-bucket! recovers the persistent 0–99 bucket from the settings interface, draw-rollout-bucket draws from OS entropy because racket/base's PRNG has a fixed seed, corrupt stored values redraw, a non-persisting store degrades gracefully). If #271 wants that piece, the shape and its tests are on branch feat/update-scaffolding (kept until #271 merges, then deletable).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RivetUpdate: own the silent-check throttle stamp (three products, three write-time semantics)

1 participant