Fifth section of #141. internal/workflows/clientholder holds the Temporal
client: start builds an empty holder, hands it to the server and the
integrations, and publishes the client once, after the worker starts and
before the first Startup hook; a second Publish panics. Every handler
and integration that starts a workflow reads the holder when a request
arrives, so a client that connects after the listener opens reaches
them without a restart; a test scans the handler configurations and
fails on any field that still holds a client.Client.
While the holder is empty:
- POST /webhooks/stripe stores the event as received, then answers 503
with Retry-After: 5 and the body "Temporal is not connected", and logs
that it answered 503 so Stripe redelivers it. A redelivery after
Temporal connects starts the event's workflow, and the processing
guard keeps a finished event from running twice.
- A Discourse event is recorded as failed with "start reconcile:
Temporal is not connected"; the sweep restores what it missed.
- Issuing or managing a grant with an end date is refused under the
end-date field with "An end date needs the expiration scheduler, which
is not connected.", after the date itself is checked, and writes
nothing. The operator page's "no scheduler" warnings, which saved the
grant and left it without an expiry, are gone.
- FedWiki's site actions and the domain claims answer that they are not
available, as they did with no Temporal configured.
The operator test harnesses and the plan-management end-to-end harness
publish a holder over a fake client whose ExecuteWorkflow succeeds, so
every bounded save keeps its result.
Full suite on reset databases: 4485 pass, 15 skip, none failed. The console booted on the
test stack and connected to Temporal. go test -race -p 1 over
clientholder, internal/server and the three integrations after
reset-test-db.sh: every package passes, no data race. make lint passes. Breaks, each caught:
- 5.10 member domains handler reads the client at construction
- 5.10 FedWiki site action handler reads the client at construction
- 5.10 Stripe environment-check handler reads the client at construction
- 5.10 the holder is a plain field in place of an atomic.Pointer (-race)
- 5.10 a client.Client field added back to MemberDomainsConfig
- 5.10 the scan ignores import names, so a temporalsdk.Client field would pass
- 5.10 Stripe StartProcessing reads the holder at registration
- 5.10 the webhook answers 500 for ErrNotConnected
- 5.10 the webhook answers 503 before the insert
- 5.10 Discourse StartReconcile calls the nil client
- 5.10 the issuance refusal after ConferGrant
- 5.10 the management refusal removed
- 5.10 the issuance refusal applied to a grant without an end date
- 5.10 the management refusal applied to a save that clears the end date
- 5.10 Publish stores a second client without panicking
- 5.10 a temporalsdk.Client field added back to a FedWiki handler configuration
- 5.10 Discourse StartReconcile reads the holder at registration
- 5.10 the issuance refusal before the parse
- 5.10 the management refusal before the parse
- 5.10 the issuance refusal is a form error, not under the end date