From 24bf59219ee5d72a1b202630d4525ab4863b9cbc Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 9 Nov 2026 22:42:00 +0100 Subject: [PATCH] Distribution and the forge hold their caller list from its config watch, not an ask per call (issue 1966) Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- .../cmd/distribution-tools/contract_test.go | 2 +- modules/distribution/cmd/distribution-tools/main.go | 2 +- modules/distribution/internal/holder/callers.go | 12 ++++++++---- modules/gitea/internal/packageseats/holder.go | 10 ++++++---- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/modules/distribution/cmd/distribution-tools/contract_test.go b/modules/distribution/cmd/distribution-tools/contract_test.go index d2453f9ea..7bd5c1e22 100644 --- a/modules/distribution/cmd/distribution-tools/contract_test.go +++ b/modules/distribution/cmd/distribution-tools/contract_test.go @@ -57,7 +57,7 @@ func TestTheVerbsSpeakTheSeatsContract(t *testing.T) { t.Errorf("%s's body %s is not the contract's: %v", event, b, err) } } - // The caller list is read on each call: one that cannot be read answers no verb, and registry_callers says it as read. + // The caller list is read held: one never read answers no verb, and registry_callers says it as read. unread := func() (holder.Callers, error) { return nil, errors.New("config refused") } for _, tool := range tools(&holder.Verbs{}, kept[holder.Window]{}, unread) { if tool.Name == holder.ImageSeat+"."+holder.VerbVersions { diff --git a/modules/distribution/cmd/distribution-tools/main.go b/modules/distribution/cmd/distribution-tools/main.go index dc80fc85d..4270a2adb 100644 --- a/modules/distribution/cmd/distribution-tools/main.go +++ b/modules/distribution/cmd/distribution-tools/main.go @@ -248,7 +248,7 @@ func arg[T any](args map[string]any) (T, error) { func str(args map[string]any, k string) string { s, _ := args[k].(string); return strings.TrimSpace(s) } -// tools are distribution's tools over v; each call that checks a caller reads the caller list on that call (callers: +// tools are distribution's tools over v; each call that checks a caller reads the caller list held (callers: // the config value as mesh-config resolves it now), so an operator's change of it holds from the next call on. func tools(v *holder.Verbs, windows kept[holder.Window], callers func() (holder.Callers, error)) []stdio.Tool { now := func() (*holder.Verbs, error) { diff --git a/modules/distribution/internal/holder/callers.go b/modules/distribution/internal/holder/callers.go index b00894c82..b3021139e 100644 --- a/modules/distribution/internal/holder/callers.go +++ b/modules/distribution/internal/holder/callers.go @@ -93,11 +93,15 @@ func ParseCallers(raw string) (Callers, error) { return selfNotReleasing(c) } -// ConfiguredCallers is the config value `callers` as mesh-config resolved it for this machine, read through the tools -// runtime's stdio.Config on each call (never an environment variable: nothing renders a config value into a -// program's environment); unset is DefaultCallers, and Self on release's list is refused as ParseCallers refuses it. +// configured holds the config value `callers`: asked of the runtime once, by a watch, and replaced on each change of +// the value, so a call never asks (issue 1966: an ask that timed out refused every verb). +var configured = stdio.HoldVerbCallers(CallersConfig, VerbsOf(ImageSeat), DefaultCallers()) + +// ConfiguredCallers is the config value `callers` as mesh-config resolved it for this machine, held from the tools +// runtime's watch of it (never an environment variable: nothing renders a config value into a program's environment); +// unset is DefaultCallers, and Self on release's list is refused as ParseCallers refuses it. func ConfiguredCallers() (Callers, error) { - c, err := stdio.ConfiguredVerbCallers(CallersConfig, VerbsOf(ImageSeat), DefaultCallers()) + c, err := configured() if err != nil { return nil, err } diff --git a/modules/gitea/internal/packageseats/holder.go b/modules/gitea/internal/packageseats/holder.go index 244f1322d..ea56b67f0 100644 --- a/modules/gitea/internal/packageseats/holder.go +++ b/modules/gitea/internal/packageseats/holder.go @@ -77,10 +77,12 @@ func DefaultCallers() Callers { VerbVersions: {stdio.AnyCaller}} } -// ConfiguredCallers is the config value `callers` as mesh-config resolved it; unset is DefaultCallers. -func ConfiguredCallers() (Callers, error) { - return stdio.ConfiguredVerbCallers("callers", Verbs, DefaultCallers()) -} +// configured holds the config value `callers`: asked of the runtime once, by a watch, and replaced on each change of +// the value, so a call never asks (issue 1966). +var configured = stdio.HoldVerbCallers("callers", Verbs, DefaultCallers()) + +// ConfiguredCallers is the config value `callers` as mesh-config resolved it, held from its watch; unset is DefaultCallers. +func ConfiguredCallers() (Callers, error) { return configured() } // Publish is a publish as the seats' contract names it (mesh-contracts npmpackageregistry and gopackageregistry share // one shape): what the tools bundle reads from either seat's PublishInput.