-
Notifications
You must be signed in to change notification settings - Fork 780
Open
Description
There is a reproducible data race in go-binance websocket implementation when reconnecting, detected by Go race detector.
The race happens between:
(*websocket.Conn).ReadMessage() / advanceFrame()
(*websocket.Conn).SetPingHandler()
Both operate on the same *websocket.Conn concurrently.
According to gorilla/websocket documentation, connection handlers (SetPingHandler, SetPongHandler) must not be modified concurrently with reads.
This race is not visible without -race, but is consistently reproducible when forcing reconnects.
Minimal reproduce:
package main
import (
"log"
"time"
binance "github.com/adshao/go-binance/v2"
)
func main() {
symbols := []string{"BTCUSDT"}
for {
doneC, stopC, err := binance.WsCombinedBookTickerServe(
symbols,
func(event *binance.WsBookTickerEvent) {},
func(err error) {
log.Println("ws error:", err)
},
)
if err != nil {
log.Fatal(err)
}
select {
case <-doneC:
case <-time.After(20 * time.Second):
}
// Force reconnect
close(stopC)
time.Sleep(500 * time.Millisecond)
}
}go run -race main.goStack trace:
2026/01/24 18:01:07 starting ws...
2026/01/24 18:01:18 forcing reconnect
2026/01/24 18:01:19 starting ws...
2026/01/24 18:01:31 forcing reconnect
2026/01/24 18:01:31 starting ws...
2026/01/24 18:01:43 forcing reconnect
2026/01/24 18:01:44 starting ws...
2026/01/24 18:01:55 forcing reconnect
2026/01/24 18:01:56 starting ws...
==================
WARNING: DATA RACE
Read at 0x00c0002803e0 by goroutine 53:
github.com/gorilla/websocket.(*Conn).advanceFrame()
/Users/alekseyk/go/pkg/mod/github.com/gorilla/websocket@v1.5.3/conn.go:954 +0x1e24
github.com/gorilla/websocket.(*Conn).NextReader()
/Users/alekseyk/go/pkg/mod/github.com/gorilla/websocket@v1.5.3/conn.go:1009 +0x168
github.com/gorilla/websocket.(*Conn).ReadMessage()
/Users/alekseyk/go/pkg/mod/github.com/gorilla/websocket@v1.5.3/conn.go:1093 +0x50
github.com/adshao/go-binance/v2.init.func1.1()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:96 +0x4f4
Previous write at 0x00c0002803e0 by goroutine 54:
github.com/gorilla/websocket.(*Conn).SetPingHandler()
/Users/alekseyk/go/pkg/mod/github.com/gorilla/websocket@v1.5.3/conn.go:1170 +0xdc
github.com/adshao/go-binance/v2.keepAliveWithPong()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:151 +0x230
github.com/adshao/go-binance/v2.wsServe.func1()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:39 +0x84
github.com/adshao/go-binance/v2.init.func1.1.gowrap2()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:80 +0x78
Goroutine 53 (running) created at:
github.com/adshao/go-binance/v2.init.func1()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:69 +0x770
github.com/adshao/go-binance/v2.wsServe()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:35 +0xa0
github.com/adshao/go-binance/v2.WsCombinedBookTickerServe()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket_service.go:1078 +0x3a0
main.main()
/Users/alekseyk/Projects/binance_race_on_reconnect/main.go:20 +0x210
Goroutine 54 (running) created at:
github.com/adshao/go-binance/v2.init.func1.1()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:80 +0x2f4
==================
==================
WARNING: DATA RACE
Write at 0x00c0001145f8 by goroutine 53:
??()
-:0 +0x100e52728
sync/atomic.StoreInt64()
<autogenerated>:1 +0x14
github.com/gorilla/websocket.(*Conn).advanceFrame()
/Users/alekseyk/go/pkg/mod/github.com/gorilla/websocket@v1.5.3/conn.go:954 +0x1e3c
github.com/gorilla/websocket.(*Conn).NextReader()
/Users/alekseyk/go/pkg/mod/github.com/gorilla/websocket@v1.5.3/conn.go:1009 +0x168
github.com/gorilla/websocket.(*Conn).ReadMessage()
/Users/alekseyk/go/pkg/mod/github.com/gorilla/websocket@v1.5.3/conn.go:1093 +0x50
github.com/adshao/go-binance/v2.init.func1.1()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:96 +0x4f4
Previous write at 0x00c0001145f8 by goroutine 54:
github.com/adshao/go-binance/v2.keepAliveWithPong()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:148 +0xfc
github.com/adshao/go-binance/v2.wsServe.func1()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:39 +0x84
github.com/adshao/go-binance/v2.init.func1.1.gowrap2()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:80 +0x78
Goroutine 53 (running) created at:
github.com/adshao/go-binance/v2.init.func1()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:69 +0x770
github.com/adshao/go-binance/v2.wsServe()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:35 +0xa0
github.com/adshao/go-binance/v2.WsCombinedBookTickerServe()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket_service.go:1078 +0x3a0
main.main()
/Users/alekseyk/Projects/binance_race_on_reconnect/main.go:20 +0x210
Goroutine 54 (running) created at:
github.com/adshao/go-binance/v2.init.func1.1()
/Users/alekseyk/go/pkg/mod/github.com/adshao/go-binance/v2@v2.8.10/websocket.go:80 +0x2f4
==================
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels