#Golang-Gin Websocket RLock Problem

31 messages · Page 1 of 1 (latest)

shut olive
#

Hello, My ws server crash. I couldn't find the problem Can you help me?
here my ws server code:

func wsServer() {
    var connList = make(map[string]*websocket.Conn)
    upgrader.CheckOrigin = func(r *http.Request) bool { return true }
    router.GET("/ws", func(c *gin.Context) {
        var mu = sync.RWMutex{}
        conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
        if err != nil {
            fmt.Println(err.Error())
            return
        }
        if _, ok := connList[c.Query("token")]; ok {
            connList[c.Query("token")].Close()
        }
        mu.Lock()
        connList[c.Query("token")] = conn
        mu.Unlock()
        defer func() {
            fmt.Println("kapanıyomm")
            if err := conn.Close(); err != nil {
                fmt.Println("Connection close error:", err)
            }
            mu.Lock()
            delete(connList, c.Query("token"))
            mu.Unlock()
        }()
        for {
            select {
            case <-time.After(2 * time.Second):
                mu.RLock()
                for _, conn := range connList {
                    if conn.WriteMessage(websocket.TextMessage, []byte("ping")); err != nil {
                        fmt.Println("PingMessage error:", err)
                        conn.Close()
                        return
                    }
                }
                mu.RUnlock()

            case data, _ := <-websocketHub.Listen():
                fmt.Println("ok")
                marshal, err := json.Marshal(data)
                if err != nil {
                }
                mu.RLock()
                for _, conn := range connList {
                    if err := conn.WriteMessage(websocket.TextMessage, marshal); err != nil {
                        fmt.Println("WriteMessage error:", err)
                    }
                }
                mu.RUnlock()
            }
        }
    })
    fmt.Println(router.Run(":81"))
}

i attach the errors
thanks

sonic nebula
#

Why are you using RWMutex here ?

#

What's the top of the panic btw, you just posted the stack trace but didn't included the reason why it crashed

shut olive
#

I have a lot of consumer on here. Some time It crash when try the write to map

#

then I added RWLock

sonic nebula
#

what's the top of the panic ?

#

#go-chat message

#

you are lacking the most relevant info

shut olive
#

here is the erroring code:

for {
            select {
            case <-time.After(2 * time.Second):
                mu.RLock()
                for _, conn := range connList {
                    if conn.WriteMessage(websocket.TextMessage, []byte("ping")); err != nil {
                        fmt.Println("PingMessage error:", err)
                        conn.Close()
                        return
                    }
                }
                mu.RUnlock()

            case data, _ := <-websocketHub.Listen():
                fmt.Println("ok")
                marshal, err := json.Marshal(data)
                if err != nil {
                }
                mu.RLock()
                for _, conn := range connList {
                    if err := conn.WriteMessage(websocket.TextMessage, marshal); err != nil {
                        fmt.Println("WriteMessage error:", err)
                    }
                }
                mu.RUnlock()
            }
        }
#

i couldn't see there are many stack

sonic nebula
#

it's the first one

#

scroll back up

shut olive
#

imma try find it

#

fatal error: concurrent map iteration and map write

sonic nebula
#

can you post the first stack trace too

#

including fatal error

shut olive
sonic nebula
#

ok great, exactly which line is ws.go:52 ?

shut olive
#

for _, conn := range connList {

#

and the all case ```go
case <-time.After(2 * time.Second):
mu.RLock()
for _, conn := range connList {
if conn.WriteMessage(websocket.TextMessage, []byte("ping")); err != nil {
fmt.Println("PingMessage error:", err)
conn.Close()
return
}
}
mu.RUnlock()

#

for is 52th line

#

sry its mu.Rlock()

sonic nebula
#
        if _, ok := connList[c.Query("token")]; ok {
            connList[c.Query("token")].Close()
        }
shut olive
#

bad info

sonic nebula
#

nvm that a read

#

but that looks like it should be protected too

#

You don't need an RWMutex here btw

#

it's slower than Mutex the point of RWMutex is when you have more than one reader

#

but I don't see more than one more reader

shut olive
#

I dont know work with mutex too much can you review the code

sonic nebula
#

not really I'm here to give you hints