pointers - References in go - attribute doesn't change -


i'm having hard time understanding how references in go work. want write simple in-memory publish-subscribe mechanism. here's code:

package sockets  import (     "fmt"      "github.com/gorilla/websocket" )  type hubsingleton struct {     clients map[string][]*websocket.conn }  var instance *hubsingleton  func hub() *hubsingleton {      if instance == nil {         fmt.println("new instance created")         instance = &hubsingleton{}     }     instance.clients = make(map[string][]*websocket.conn, 6)     return instance }  func (hub *hubsingleton) subscribe(channel string, socket *websocket.conn) error {     if _, ok := hub.clients[channel]; !ok {         hub.clients[channel] = make([]*websocket.conn, 0)     }     hub.clients[channel] = append(hub.clients[channel], socket)      fmt.println("subscribe: ", hub.clients)     return nil }  func (hub *hubsingleton) publish(channel string, message interface{}) {     fmt.println("publish: ", hub.clients)      if _, ok := hub.clients[channel]; !ok {         return     }     := 0; < len(hub.clients[channel]); i++ {         conn := hub.clients[channel][i]         conn.writejson(message{status: "ok", content: message})     } } 

the problem seems every time call hub().publish() or hub().subscribe() new hubsingleton.client created. well, i'm not sure happens, here's output of running program:

publish:  map[] subscribe:  map[chan:[0xc820170000]] publish:  map[] subscribe:  map[chan:[0xc82008ac80]] publish:  map[] publish:  map[] publish:  map[] subscribe:  map[chan:[0xc820170140]] publish:  map[] 

subscribers added map disapear every time call hub(). can do, make changes in map preserved between calls?

the hub function creates new client map on every call. change function to:

func hub() *hubsingleton {   if instance == nil {     fmt.println("new instance created")     instance = &hubsingleton{}     instance.clients = make(map[string][]*websocket.conn, 6)   }   return instance } 

if first call hub request handler, there's data race on instance. use lock fix race:

var (   instance *hubsingleton   mu sync.mutex )  func hub() *hubsingleton {   mu.lock()   defer mu.unlock()   if instance == nil {     fmt.println("new instance created")     instance = &hubsingleton{}     instance.clients = make(map[string][]*websocket.conn, 6)   }   return instance } 

a simpler approach initialize instance once before use:

var instance *hubsingleton  func newhub() *hubsingleton {    return &hubsingleton{clients:  make(map[string][]*websocket.conn, 6)} }  func main() {    instance = newhub()    ... } 

if publish , subscribe called concurrently handlers, there data races on clients in publish , subscribe.


Comments

Popular posts from this blog

angular - Is it possible to get native element for formControl? -

unity3d - Rotate an object to face an opposite direction -

javascript - Why jQuery Select box change event is now working? -