Skip to content

fix: race conditions in keepAlive() and wsServe() for futures, options, delivery#805

Open
DukeDeSouth wants to merge 2 commits into
ccxt:masterfrom
DukeDeSouth:fix/race-conditions-keepalive-wsserve
Open

fix: race conditions in keepAlive() and wsServe() for futures, options, delivery#805
DukeDeSouth wants to merge 2 commits into
ccxt:masterfrom
DukeDeSouth:fix/race-conditions-keepalive-wsserve

Conversation

@DukeDeSouth
Copy link
Copy Markdown

Fixes #704.

The lastResponse variable in keepAlive() is a time.Time struct shared between the ping handler goroutine (writer) and the ticker goroutine (reader) without synchronization. The base package v2/websocket.go was already fixed with atomic.Int64, but v2/futures, v2/options, and v2/delivery still had the original racy code.

This applies the same atomic pattern to all three remaining packages. I also noticed a previously unreported race on the silent bool in wsServe() — it's written in one goroutine and read in another without sync. Fixed that across all four packages (including the base) using atomic.Int32.

All existing tests pass with -race enabled. No API changes, no new dependencies, no behavior change.

Made with Cursor

…s, delivery

The lastResponse variable in keepAlive() is a time.Time shared between
the ping handler goroutine and the ticker goroutine without sync. The
base package was already fixed with atomic.Int64, but futures, options,
and delivery still had the original racy code.

This applies the same atomic pattern to all three remaining packages.
Also fixes a previously unreported race on the silent bool in wsServe()
across all four packages including the base.

Fixes ccxt#704

Made-with: Cursor
TestKeepAliveNoRace spins up a real WebSocket server that sends rapid
pings while a short-interval ticker reads lastResponse — reproduces the
data race on the original code (confirmed: FAIL without the fix).

TestWsSilentNoRace exercises the stopC → silent → ReadMessage path to
cover the second race.

Both pass consistently with -race -count=3 after the atomic fix.

Made-with: Cursor
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.

Race condition in keepAlive() due to unsynchronized access to lastResponse

1 participant