Home > Blockchain >  Gorilla/Mux & Websocket Race Condition. Is this safe?
Gorilla/Mux & Websocket Race Condition. Is this safe?

Time:03-12

I'm working on a websocket and recently started doing some tests for race conditions using race. go run -race serve.go

Getting this result:

WARNING: DATA RACE
Write at 0x0000019ab4a8 by goroutine 95:
  go-api/client.ServeWs()

Previous write at 0x0000019ab4a8 by goroutine 117:
  go-api/client.ServeWs()

I'm using gorilla/mux and am upgrading one of the requests to websockets. I wasn't sure if it was being caused by something else, but even this pretty simple setup is still showing a race condition. My guess was because websocket was being written to by both routines at the same time, but as long as both requests get upgraded, does it matter? Or is it possible a connection is being dropped due to the race condition?

    //serve.go
    mux.HandleFunc("/data", func(w http.ResponseWriter, r *http.Request) {
        client.ServeWs(w, r)
    })
//client.go
func ServeWs(w http.ResponseWriter, r *http.Request) {
    upgrader = websocket.Upgrader{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
        CheckOrigin: func(r *http.Request) bool {
            return true
        },
    }

    _, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
}

CodePudding user response:

Because the upgrader is not dependent on the request, you can create the upgrader at package-level

var upgrader = websocket.Upgrader{ ... fields as in ServeWs ... }

and remove the assignment to the upgrader from ServeWs.

func ServeWs(w http.ResponseWriter, r *http.Request) {
    c, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
    defer c.Close()
  • Related