Repository navigation
Conversation
A guard, action or reducer had no context, so a host couldn't tell a call it made back into the host from a call on another goroutine. GuardCtx, ActionCtx and AssignCtx now carry Ctx: the context the Fire was given, or context.Background() outside a Fire. The in-process bindings pass their own context through. WithContext sets the context Cast gives the reducers that settle the initial state. ActorSystem.RegisterContext registers a factory that gets the spawning step's context, so it can Cast its child with it. A child's own callbacks already get the context its delivery carries. The change is additive. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
A draft PR now runs only the gate, which fails with a note that CI runs once the PR is marked ready. Marking it ready (ready_for_review) runs the full CI and CodeQL, as does every later push to a ready PR. The gate fails rather than skips on a draft: a skipped required check counts as passing for that commit, so a PR could otherwise be marked ready and merged before its CI had run. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
Review found that a guard registered with BindGuard was adapted with a background context, dropping the Fire's context the kernel now passes. Its EvalGuard now gets the Fire's context. Callbacks also see the context as the middleware chain passes it down, not only the one Fire was called with. Docs: WithContext reaches the guards and actions that settle the initial state as well as its reducers, and Cast settles to completion even if that context has ended. The ActorSystem doc says the parent Instance still needs one goroutine at a time. The site docs mention Ctx. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
…in regions Review follow-ups: - Cast clears the callbacks' context with defer, as Fire does. - Tests: an eventless transition settling during Cast, and a transition inside a parallel region, see the expected context. - Ctx's doc no longer suggests PlanPath runs actions or reducers. - The guards and actors pages mention Ctx and RegisterContext, the deferred-surface notes record Cast's WithContext, and CONTRIBUTING says CI runs on ready PRs. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
ReviewEach dimension was attacked by an AI reviewer working from a clean context. The reviewers could only read code; they traced paths by hand. I ran the tests and mutation checks. All seven dimensions are confirmed.
Fixed
Not changed
|
|
Review at 1aea966. Build, vet, tests pass. One fix needed before merge. Must fix
Should fix
Nits
|
Review follow-ups: - A guard registered with BindGuard whose EvalGuard fails after the Fire's context ended now stops the Fire with the context's error. It was read as false, so another transition was chosen and its callbacks ran under the ended context until the next cancellation check rolled the Fire back. An eventless transition chosen while the context ended isn't committed either. The CHANGELOG lists this under Changed. - Ctx's doc says not to branch on it: a replay runs the same callbacks under a different context. - A test covers RestoreActors through RegisterContext. - The deferred-surface note no longer reads as a promise that clashes with Cast's WithContext. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
…rds alike Review follow-ups: - Cast gives its callbacks WithContext's values without its cancellation or deadline. A bound guard that honored an ended context could fail there and quietly send the settle down another transition, because Cast settles to completion and has no error to report. - A guard stopped by an ended context no longer reports a guard panic or failure in the Trace on any path: named guards, guard expressions, parallel regions and the parallel state itself. - The Fire's error names the bound guard and keeps its own error, while still matching the context's. - Tests pin each of these, and a Fire whose eventless guard was canceled with nothing chosen. - Docs: ContextActorBehavior covers restore; the site pages say not to branch on Ctx. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
An eventless transition's guard stopped by an ended context was read as not passing, so the Fire reported a bare context error, without the guard's name or the binding's own error. Eventless selection now stops with the guard's error, as event-driven evaluation does. A test covers both. Docs: a nested Fire clears the outer Fire's raised events; a bound guard's cancellation check reads the context it got, as middleware passed it down; at Cast, Ctx carries the values of WithContext's context. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
The Fire's error embedded the binding's error as text only, so a host couldn't match its sentinel with errors.Is, though the CHANGELOG said it was wrapped. It now wraps both the context's error and the binding's. The test checks errors.Is for each. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
… error A guard that panicked with a value wrapping context.Canceled was taken for a guard stopped by its ended context. Canceled guards now carry the kernel's own marker, so only those skip the guard-panic outcome. Tests: that case, a region's eventless transition settling during Cast, and a note that a nil Ctx fails the context tests. Signed-off-by: Ray Karnes <ray.karnes@stablekernel.com>
|
Thanks for the review. Addressed in 2f3c928 through f2eb64c. Your must-fix: done. A Reviewing the fix also turned up a Your should-fix items: all done.
Your nit: done. The comment at Also: a cancelled guard no longer shows as a guard panic or failure in the Trace on any path. The review summary below this comment has the details. |
Review after the maintainer's commentsThe maintainer's review is addressed in 2f3c928 through f2eb64c. Each changed dimension was attacked again by an AI reviewer working from a clean context, until it had no blockers. The reviewers could only read code; I ran the tests and the mutation checks. All dimensions are confirmed.
Fixed
Not changed
|
What this change does
Guards, actions and reducers now get the context of the step running them, so a host can tell when one of them calls back into it.
GuardCtx,ActionCtxandAssignCtxhave a newCtxfield: the context theFirewas given. Outside aFire, such as duringPlanPath, it'scontext.Background(), never nil. AFirenested inside a callback on the same instance restores the outer context when it returns.EvalGuard,EvalAction,EvalAssign) through to the function they wrap.WithContextsets the contextCastgives the guards, actions and reducers that settle the initial state.ActorSystem.RegisterContextregisters aContextActorBehavior, an actor factory that gets the context of the step spawning or restoring the actor, so it canCastits childWithContext. A child's own callbacks already get the context its delivery carries.Registeris unchanged.BindGuardgets the Fire's context throughEvalGuard, where it used to get a background one, and callbacks see the context as the middleware chain passes it down.It's additive: no existing signature changes.
CI on drafts. This PR also stops CI and CodeQL running on draft PRs. A draft runs only the required
gatecheck, which fails in a few seconds with "Draft PR: CI runs when it's marked ready for review". Marking a PR ready runs the full CI and CodeQL, as does every later push to it. The gate fails rather than skips on a draft: a skipped required check counts as passing for that commit, so a PR could otherwise be marked ready and merged before its CI ran. CONTRIBUTING says so.Why
#243 makes a durable Handle hold a lock for each step. Code that runs under that lock and calls back into the same Handle would wait forever. A service gets the step's context, so #243 can recognize a call carrying it and return
ErrReentrantStepinstead. Guards, actions, reducers and actor factories had no context to pass back, so the same mistake there still deadlocked. With this change, a callback that passesin.Ctxback into its Handle getsErrReentrantSteptoo. Once both land, #243's docs will say so.It also lets work under review stay a draft without spending CI time, as agreed with the maintainers.
Relates to: #214, #243
Evidence
On
GOTOOLCHAIN=go1.27.3:go test -race ./state/... ./durable/... ./cluster/...go test ./...inexamples/dispatchande2ego vet ./...in every workspace modulegolangci-lintonstateactionlintonci.ymlandcodeql.ymlgateran (3 s, failed with the draft message); CodeQL skippedThe new tests in
state/callback_context_test.gocover a guard, an action and a reducer seeing the Fire's context, an entry reducer on a later Fire,Castwith and withoutWithContext,PlanPath, a nestedFire, andRegisterContextthrough spawn,Castand delivery, aBindGuardbinding, middleware, an eventless transition settling duringCast, and a parallel region. Each fails when the code it covers is removed.Checklist
git commit -s) per the DCOtype: subject)mage checkpasses locally (lint + race tests + govulncheck): not run as a whole; the parts above were run individually