split mutex in List,Current and Read,Write

This commit is contained in:
Martin/Geno 2018-07-25 09:51:57 +02:00
parent f631ac057b
commit 50a109dee0
No known key found for this signature in database
GPG Key ID: 9D7D3C6BFF600C6A
3 changed files with 21 additions and 10 deletions

View File

@ -20,7 +20,8 @@ type Nodes struct {
iface string iface string
notifyNodeFunc []func(*Node, bool) notifyNodeFunc []func(*Node, bool)
notifyStatsFunc []func(*runtimeYanic.GlobalStats) notifyStatsFunc []func(*runtimeYanic.GlobalStats)
sync.Mutex ListMux sync.RWMutex
CurrentMux sync.RWMutex
} }
func NewNodes(path string, iface string, mgmt *ssh.Manager) *Nodes { 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) log.Warnf("wrong wifi5 channel for '%s'", node.NodeID)
return false return false
} }
nodes.Lock() nodes.ListMux.Lock()
defer nodes.Unlock()
if n, ok := nodes.List[node.NodeID]; ok { if n, ok := nodes.List[node.NodeID]; ok {
node.Address = n.Address node.Address = n.Address
go node.SSHUpdate(nodes.ssh, nodes.iface, n) go node.SSHUpdate(nodes.ssh, nodes.iface, n)
log.Info("update node", node.NodeID) log.Info("update node", node.NodeID)
} }
nodes.List[node.NodeID] = node nodes.List[node.NodeID] = node
nodes.ListMux.Unlock()
nodes.notifyNode(node, true) nodes.notifyNode(node, true)
return true return true
} }
func (nodes *Nodes) Updater() { func (nodes *Nodes) Updater() {
nodes.Lock() nodes.ListMux.RLock()
defer nodes.Unlock() nodes.CurrentMux.RLock()
for nodeid, node := range nodes.List { for nodeid, node := range nodes.List {
if n, ok := nodes.Current[nodeid]; ok { if n, ok := nodes.Current[nodeid]; ok {
go node.SSHUpdate(nodes.ssh, nodes.iface, n) go node.SSHUpdate(nodes.ssh, nodes.iface, n)
} }
} }
nodes.ListMux.RUnlock()
nodes.CurrentMux.RUnlock()
log.Info("updater per ssh") log.Info("updater per ssh")
} }
func (nodes *Nodes) Saver() { func (nodes *Nodes) Saver() {
nodes.Lock() nodes.ListMux.RLock()
file.SaveJSON(nodes.statePath, nodes) file.SaveJSON(nodes.statePath, nodes)
nodes.Unlock() nodes.ListMux.RUnlock()
log.Debug("saved state file") log.Debug("saved state file")
} }

View File

@ -32,8 +32,7 @@ func (conn *YanicDB) InsertNode(n *runtimeYanic.Node) {
} }
node.Lastseen = jsontime.Now() node.Lastseen = jsontime.Now()
logger := log.WithField("method", "LearnNode").WithField("node_id", node.NodeID) logger := log.WithField("method", "LearnNode").WithField("node_id", node.NodeID)
conn.nodes.Lock() conn.nodes.ListMux.Lock()
defer conn.nodes.Unlock()
if lNode := conn.nodes.List[node.NodeID]; lNode != nil { if lNode := conn.nodes.List[node.NodeID]; lNode != nil {
lNode.Lastseen = jsontime.Now() lNode.Lastseen = jsontime.Now()
lNode.Stats = node.Stats lNode.Stats = node.Stats
@ -41,9 +40,12 @@ func (conn *YanicDB) InsertNode(n *runtimeYanic.Node) {
conn.nodes.List[node.NodeID] = node conn.nodes.List[node.NodeID] = node
conn.nodes.notifyNode(node, true) conn.nodes.notifyNode(node, true)
} }
conn.nodes.ListMux.Unlock()
conn.nodes.CurrentMux.Lock()
if _, ok := conn.nodes.Current[node.NodeID]; ok { if _, ok := conn.nodes.Current[node.NodeID]; ok {
conn.nodes.Current[node.NodeID] = node conn.nodes.Current[node.NodeID] = node
conn.nodes.notifyNode(node, false) conn.nodes.notifyNode(node, false)
conn.nodes.CurrentMux.Unlock()
return return
} }
// session := nodes.ssh.ConnectTo(node.Address) // 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) logger.Infof("new node with uptime: %s", uptime)
conn.nodes.Current[node.NodeID] = node conn.nodes.Current[node.NodeID] = node
conn.nodes.CurrentMux.Unlock()
conn.nodes.ListMux.Lock()
if lNode := conn.nodes.List[node.NodeID]; lNode != nil { if lNode := conn.nodes.List[node.NodeID]; lNode != nil {
lNode.Address = node.Address lNode.Address = node.Address
go lNode.SSHUpdate(conn.nodes.ssh, conn.nodes.iface, node) go lNode.SSHUpdate(conn.nodes.ssh, conn.nodes.iface, node)
} }
conn.nodes.ListMux.Unlock()
conn.nodes.notifyNode(node, false) conn.nodes.notifyNode(node, false)
} }

View File

@ -13,13 +13,16 @@ var wifi5Channels []uint32
func (ws *WebsocketServer) connectHandler(logger *log.Entry, msg *wsLib.Message) error { func (ws *WebsocketServer) connectHandler(logger *log.Entry, msg *wsLib.Message) error {
msg.From.Write(&wsLib.Message{Subject: MessageTypeStats, Body: ws.nodes.Statistics}) msg.From.Write(&wsLib.Message{Subject: MessageTypeStats, Body: ws.nodes.Statistics})
ws.nodes.ListMux.RLock()
for _, node := range ws.nodes.List { for _, node := range ws.nodes.List {
msg.From.Write(&wsLib.Message{Subject: MessageTypeSystemNode, Body: node}) msg.From.Write(&wsLib.Message{Subject: MessageTypeSystemNode, Body: node})
} }
ws.nodes.ListMux.RUnlock()
ws.nodes.CurrentMux.RLock()
for _, node := range ws.nodes.Current { for _, node := range ws.nodes.Current {
msg.From.Write(&wsLib.Message{Subject: MessageTypeCurrentNode, Body: node}) 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: MessageTypeChannelsWifi24, Body: wifi24Channels})
msg.From.Write(&wsLib.Message{Subject: MessageTypeChannelsWifi5, Body: wifi5Channels}) msg.From.Write(&wsLib.Message{Subject: MessageTypeChannelsWifi5, Body: wifi5Channels})
logger.Debug("done") logger.Debug("done")