Skip to content

fix: SessionStore race conditions and async initialization (WAPI-1118)#71

Merged
chakra-guy merged 1 commit intomainfrom
cyfrin/wapi-1118
Feb 27, 2026
Merged

fix: SessionStore race conditions and async initialization (WAPI-1118)#71
chakra-guy merged 1 commit intomainfrom
cyfrin/wapi-1118

Conversation

@chakra-guy
Copy link
Collaborator

@chakra-guy chakra-guy commented Feb 25, 2026

Summary

Fixes race conditions in SessionStore and replaces fire-and-forget garbage collection with proper async initialization.

  • BREAKING: SessionStore constructor is now private; use await SessionStore.create(kvstore) instead
  • SessionStore.create() runs garbage collection to completion before returning
  • Mutex protection on master list read-modify-write operations (addToMasterList, removeFromMasterList)
  • Updated all call sites across packages, apps, and tests

Note: This PR is based on cyfrin/wapi-1116 and should be merged after PR #70.

Jira

Test plan

  • New test: GC completes before first public method returns
  • New test: concurrent session sets don't lose entries (mutex)
  • All unit tests pass (68/68)
  • Lint passes
  • All new SessionStore(kvstore) call sites updated to await SessionStore.create(kvstore)

Note

Medium Risk
Medium risk because it changes the SessionStore instantiation API (breaking) and modifies persistence semantics around master list updates and startup garbage collection, which can affect session resumption and cleanup timing across clients.

Overview
Fixes SessionStore race conditions and startup GC timing. The SessionStore constructor is now private and callers must use await SessionStore.create(kvstore), which runs garbage collection to completion before the store is used.

Master-list updates are now mutex-protected to avoid lost entries under concurrent set/delete operations, with new unit tests covering GC-before-use and concurrent writes; all apps/tests were updated to the async factory API and async-mutex was added as a core dependency.

Written by Cursor Bugbot for commit 90bf894. This will update automatically on new commits. Configure here.

@socket-security
Copy link

socket-security bot commented Feb 25, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedasync-mutex@​0.5.010010010080100

View full report

@chakra-guy chakra-guy force-pushed the cyfrin/wapi-1118 branch 3 times, most recently from 4ce2384 to fcf6205 Compare February 25, 2026 08:45
adonesky1
adonesky1 previously approved these changes Feb 26, 2026
Copy link

@adonesky1 adonesky1 left a comment

Choose a reason for hiding this comment

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

Looks right to me!

Base automatically changed from cyfrin/wapi-1116 to main February 27, 2026 10:20
@chakra-guy chakra-guy dismissed adonesky1’s stale review February 27, 2026 10:20

The base branch was changed.

Replace fire-and-forget garbage collection with an async factory method
(SessionStore.create) that completes GC before the store is usable.
Add mutex protection around master list read-modify-write operations to
prevent concurrent session set/delete from corrupting the list.

BREAKING: SessionStore constructor is now private. Use
await SessionStore.create(kvstore) instead of new SessionStore(kvstore).
@chakra-guy chakra-guy merged commit 3334551 into main Feb 27, 2026
12 checks passed
@chakra-guy chakra-guy deleted the cyfrin/wapi-1118 branch February 27, 2026 10:38
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.

3 participants