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

Issue

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
    }
}

Solution

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()

Answered By – Zombo

Answer Checked By – Willingham (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.