Skip to content

fix: use separate session with timeout in session.done() handler - #491

Open
annatar wants to merge 4 commits into
devfrom
fix/session-context-close-with-timeout
Open

fix: use separate session with timeout in session.done() handler#491
annatar wants to merge 4 commits into
devfrom
fix/session-context-close-with-timeout

Conversation

@annatar

@annatar annatar commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Identified from a test failing on CI. Running this locally with
go test -v -count 7000 -timeout 10m ./tests -run TestNoopReceivesPendingDeletionUpdates will produce the same issue and

The issue being the context passed to done is the same one that gets cancelled, which in session.serve gets anreturn ctx.Err() which .done(ctx) is called on defer. On the waterfall shutdown removeState's first context gated DB read fails with the context cancelled, the function returns early, state.Close(ctx) never runs, thus the DB handle is never released.

On macOS/Linux this would not pose an issue, but on Windows TempDir RemoveAll runs right after this so the .db file is still inuse making the test fail.

Added a new releaseContext with a 5s timeout, that is used on RemoveState.

Re-running the test multiple times using count 7000 ~42k times, doesn't fail now.

Comment thread internal/session/session.go Outdated

if s.state != nil {
if err := s.state.ReleaseState(ctx); err != nil {
releaseContext, cancel := context.WithTimeout(ctx, 5*time.Second)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still inherit the ctx cancellation from the parent even in this case. The DB transaction will and should still fail.

Now why that fixes the underlying flaky test is a different topic.

Plus this impacts prod. We now have exactly 5 secs to release the state.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how it resolves the issue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, this leads to a bigger issue; the user state WG won't be released if the transaction fails first, preventing server shutdown and removing the user from the server.

So we ought to either re-order the operations downstream on releaseState, or perhaps introduce a separate context for this operation.

Either way it's good you picked this up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was getting contextcheck lint errors when using a brand new context, but I guess we don't need to pass the parent context, and I guess a timeout context doesn't make sense, since RemoveState down the patch, calls user.statesWG.Done so when the whole procedure finishes we defer cancel() with the new context.

Although this means that we allow remove state to finish even if the context is cancelled, which I guess should be the case?

@annatar
annatar force-pushed the fix/session-context-close-with-timeout branch from 124e802 to 740bb8e Compare August 19, 2026 08:18
@annatar
annatar force-pushed the fix/literals-fetch-before-db-transaction-recovery-mailbox branch from 3dab740 to 085b138 Compare August 19, 2026 08:21
@annatar
annatar force-pushed the fix/session-context-close-with-timeout branch 2 times, most recently from 3d948c7 to cd86397 Compare August 19, 2026 10:47
@annatar
annatar force-pushed the fix/literals-fetch-before-db-transaction-recovery-mailbox branch from 085b138 to 3f387d1 Compare August 19, 2026 10:47
Identified from a test failing on CI. Running this locally with `go test
-v -count 7000 -timeout 10m ./tests -run TestNoopReceivesPendingDeletionUpdates` will produce the same issue and

The issue being the context passed to `done` is the same one that gets
cancelled, which in session `retrun ctx.Err()`, on shutdown
removeState's first context gated DB read fails with the context
cancelled, the function returns early, `state.Close(ctx)` never runs,
thus the DB handle is never released. On macOS/Linux this would not pose
an issue, but on Windows `TempDir RemoveAll` runs right after this so
the `.db` file is still inuse making the test fail.

Added a new releaseContext with a 5s timeout, that is used on
RemoveState.

Re-running the test multiple times using `count 7000` ~42k times,
doesn't fail now.
@annatar
annatar force-pushed the fix/literals-fetch-before-db-transaction-recovery-mailbox branch from 3f387d1 to 5173834 Compare August 19, 2026 13:29
@annatar
annatar force-pushed the fix/session-context-close-with-timeout branch from cd86397 to 5846824 Compare August 19, 2026 13:29
Base automatically changed from fix/literals-fetch-before-db-transaction-recovery-mailbox to dev August 19, 2026 14:00
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.

2 participants