carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "context"
5 "log"
6 "time"
7
8 "github.com/carlosframework/platform/internal/release"
9)
10
11// bumpSerial announces "the bucket has news" (carlos-deploy spec §3) after a
12// write a box loop consumes. Log-only on failure and clamped to 2s: a lost
13// bump costs latency (the hourly floor still converges), and no user-facing
14// write may fail or stall because its announcement did.
15//
16// Every call site sits strictly AFTER the handler's own successful write, next
17// to its audit row — never before a gate, and never in place of one. The
18// serial carries no authority at all (it is the one unsigned object in the
19// bucket); the worst a spurious bump can do is make a box run its ordinary
20// signature-verified pass set a little early.
21//
22// context.WithoutCancel is the whole point of the ctx handling here: the
23// caller's context is the REQUEST's, and by the time a bump runs the write it
24// announces has already landed and is irreversible. A client that hangs up in
25// that window (a CI runner killed mid-promote, a closed laptop, a proxy
26// timeout) would otherwise cancel the announcement for a change that is
27// permanently in the bucket — the fleet then waits out the hourly floor for a
28// deploy that already happened, with nothing in any log to say why. The 2s
29// clamp still applies, measured from here: detached from cancellation, not
30// from time.
31func (s *Server) bumpSerial(ctx context.Context) {
32 if s.cfg.Releases == nil {
33 return // no bucket on this console: nothing to announce into
34 }
35 ctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 2*time.Second)
36 defer cancel()
37 if err := release.BumpSerial(ctx, s.cfg.Releases, time.Now()); err != nil {
38 log.Printf("console: serial bump: %v (boxes fall back to the hourly pass)", err)
39 }
40}
41