From 50a109dee04c88e1cc2c30c68e73065f1d4db486 Mon Sep 17 00:00:00 2001 From: Martin/Geno Date: Wed, 25 Jul 2018 09:51:57 +0200 Subject: [PATCH] split mutex in List,Current and Read,Write --- runtime/nodes.go | 17 ++++++++++------- runtime/yanic.go | 9 +++++++-- websocket/hd_connect.go | 5 ++++- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/runtime/nodes.go b/runtime/nodes.go index da38e22..0fa4cce 100644 --- a/runtime/nodes.go +++ b/runtime/nodes.go @@ -20,7 +20,8 @@ type Nodes struct { iface string notifyNodeFunc []func(*Node, bool) notifyStatsFunc []func(*runtimeYanic.GlobalStats) - sync.Mutex + ListMux sync.RWMutex + CurrentMux sync.RWMutex } func NewNodes(path string, iface string, mgmt *ssh.Manager) *Nodes { @@ -67,32 +68,34 @@ func (nodes *Nodes) UpdateNode(node *Node) bool { log.Warnf("wrong wifi5 channel for '%s'", node.NodeID) return false } - nodes.Lock() - defer nodes.Unlock() + nodes.ListMux.Lock() if n, ok := nodes.List[node.NodeID]; ok { node.Address = n.Address go node.SSHUpdate(nodes.ssh, nodes.iface, n) log.Info("update node", node.NodeID) } nodes.List[node.NodeID] = node + nodes.ListMux.Unlock() nodes.notifyNode(node, true) return true } func (nodes *Nodes) Updater() { - nodes.Lock() - defer nodes.Unlock() + nodes.ListMux.RLock() + nodes.CurrentMux.RLock() for nodeid, node := range nodes.List { if n, ok := nodes.Current[nodeid]; ok { go node.SSHUpdate(nodes.ssh, nodes.iface, n) } } + nodes.ListMux.RUnlock() + nodes.CurrentMux.RUnlock() log.Info("updater per ssh") } func (nodes *Nodes) Saver() { - nodes.Lock() + nodes.ListMux.RLock() file.SaveJSON(nodes.statePath, nodes) - nodes.Unlock() + nodes.ListMux.RUnlock() log.Debug("saved state file") } diff --git a/runtime/yanic.go b/runtime/yanic.go index 2db7fd6..cad9941 100644 --- a/runtime/yanic.go +++ b/runtime/yanic.go @@ -32,8 +32,7 @@ func (conn *YanicDB) InsertNode(n *runtimeYanic.Node) { } node.Lastseen = jsontime.Now() logger := log.WithField("method", "LearnNode").WithField("node_id", node.NodeID) - conn.nodes.Lock() - defer conn.nodes.Unlock() + conn.nodes.ListMux.Lock() if lNode := conn.nodes.List[node.NodeID]; lNode != nil { lNode.Lastseen = jsontime.Now() lNode.Stats = node.Stats @@ -41,9 +40,12 @@ func (conn *YanicDB) InsertNode(n *runtimeYanic.Node) { conn.nodes.List[node.NodeID] = node conn.nodes.notifyNode(node, true) } + conn.nodes.ListMux.Unlock() + conn.nodes.CurrentMux.Lock() if _, ok := conn.nodes.Current[node.NodeID]; ok { conn.nodes.Current[node.NodeID] = node conn.nodes.notifyNode(node, false) + conn.nodes.CurrentMux.Unlock() return } // session := nodes.ssh.ConnectTo(node.Address) @@ -56,10 +58,13 @@ func (conn *YanicDB) InsertNode(n *runtimeYanic.Node) { logger.Infof("new node with uptime: %s", uptime) conn.nodes.Current[node.NodeID] = node + conn.nodes.CurrentMux.Unlock() + conn.nodes.ListMux.Lock() if lNode := conn.nodes.List[node.NodeID]; lNode != nil { lNode.Address = node.Address go lNode.SSHUpdate(conn.nodes.ssh, conn.nodes.iface, node) } + conn.nodes.ListMux.Unlock() conn.nodes.notifyNode(node, false) } diff --git a/websocket/hd_connect.go b/websocket/hd_connect.go index 2b8df33..9b86bab 100644 --- a/websocket/hd_connect.go +++ b/websocket/hd_connect.go @@ -13,13 +13,16 @@ var wifi5Channels []uint32 func (ws *WebsocketServer) connectHandler(logger *log.Entry, msg *wsLib.Message) error { msg.From.Write(&wsLib.Message{Subject: MessageTypeStats, Body: ws.nodes.Statistics}) - + ws.nodes.ListMux.RLock() for _, node := range ws.nodes.List { msg.From.Write(&wsLib.Message{Subject: MessageTypeSystemNode, Body: node}) } + ws.nodes.ListMux.RUnlock() + ws.nodes.CurrentMux.RLock() for _, node := range ws.nodes.Current { msg.From.Write(&wsLib.Message{Subject: MessageTypeCurrentNode, Body: node}) } + ws.nodes.CurrentMux.RUnlock() msg.From.Write(&wsLib.Message{Subject: MessageTypeChannelsWifi24, Body: wifi24Channels}) msg.From.Write(&wsLib.Message{Subject: MessageTypeChannelsWifi5, Body: wifi5Channels}) logger.Debug("done")