Skip to content

fix: close the DeleteEnvironment check-then-act race on a concurrent CreateSession - #81

Open
AmirF194 wants to merge 1 commit into
tokencanopy:mainfrom
AmirF194:fix/environment-delete-race-dangling-session
Open

fix: close the DeleteEnvironment check-then-act race on a concurrent CreateSession#81
AmirF194 wants to merge 1 commit into
tokencanopy:mainfrom
AmirF194:fix/environment-delete-race-dangling-session

Conversation

@AmirF194

Copy link
Copy Markdown
Contributor

Fixes #80.

Replaced the separate CountSessionsByEnvironment + DeleteEnvironment pair with one repository call, DeleteEnvironmentUnlessReferenced, so the check and the write can't be split by a concurrent CreateSession.

pgstore folds the check into the DELETE's own WHERE ... NOT EXISTS (...). Zero rows affected is ambiguous (already gone vs. still referenced), so it disambiguates with a follow-up GetEnvironment, same shape SetEnvironmentSnapshot already uses for stale-vs-not-found. memstore holds m.mu across the whole check-and-delete instead of two separate lock/unlock pairs.

TestDeleteEnvironmentSeesASessionCreatedRightBeforeItsOwnDelete seeds the racer session from inside the repository's own delete call, the latest point a concurrent CreateSession could still land. Reverting just the service-layer hunk (still calling the old two-step path) makes it fail: 204 instead of 409, environment gone despite the live session.

go test -race ./controlapp/... ./internal/controld/... passes, including the new test and repotest's E9 case against both memstore and Postgres. go vet and gofmt are clean on the changed files.

…CreateSession

CountSessionsByEnvironment and DeleteEnvironment ran as two separate
repository calls, so a CreateSession landing between them survived a
delete that had already decided nothing referenced the environment.

Replace both with DeleteEnvironmentUnlessReferenced: pgstore folds the
guard into the DELETE's own WHERE NOT EXISTS, memstore holds one lock
across the whole check-and-delete. Fixes tokencanopy#80.
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.

DeleteEnvironment's session-count guard is check-then-act, so a raced CreateSession survives delete with a dangling, capability-less session

1 participant