|
|
|
@ -2,7 +2,7 @@ package server
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"sync"
|
|
|
|
|
"fmt"
|
|
|
|
|
_ "fmt"
|
|
|
|
|
"FRMS/internal/pkg/logging"
|
|
|
|
|
)
|
|
|
|
|
// allows for multiple readers/writers
|
|
|
|
@ -52,9 +52,9 @@ func NewStatusMonitor(t string, id uint32, sys *SystemViewer) *StatusMonitor {
|
|
|
|
|
} else {
|
|
|
|
|
// tui status monitor
|
|
|
|
|
sbuf := NewBuffer()
|
|
|
|
|
sm.ReactorChan, sbuf["Reactor"] = sys.AddListener(id,0)
|
|
|
|
|
//sm.ReactorChan, sbuf["Reactor"] = sys.AddListener(id,0)
|
|
|
|
|
sm.DevBuf = &devbuf{Buf:sbuf} // makes it easier to work with
|
|
|
|
|
go sm.Listen(sm.ReactorChan)
|
|
|
|
|
go sm.UpdateListener(id,0)
|
|
|
|
|
}
|
|
|
|
|
return sm
|
|
|
|
|
}
|
|
|
|
@ -70,7 +70,7 @@ func (s *StatusMonitor) GenerateIds() {
|
|
|
|
|
|
|
|
|
|
func (s *StatusMonitor) Send(d *DeviceInfo, dtype string) {
|
|
|
|
|
d.TransactionId = <-s.TransactionId
|
|
|
|
|
logging.Debug(logging.DClient,"SYS 01 Updating %s Info (%s, %s)", d.Type, d.Status, d.Data)
|
|
|
|
|
logging.Debug(logging.DClient,"SYS 01 Sending update for: %s (%s)", d.Type, d.Status)
|
|
|
|
|
if dtype == "Reactor" {
|
|
|
|
|
s.ReactorChan <-d
|
|
|
|
|
} else {
|
|
|
|
@ -83,6 +83,9 @@ func (s *StatusMonitor) GetBuffer() []*DeviceInfo {
|
|
|
|
|
s.DevBuf.Lock()
|
|
|
|
|
defer s.DevBuf.Unlock()
|
|
|
|
|
res := []*DeviceInfo{}
|
|
|
|
|
if len(s.DevBuf.Buf["Reactor"]) != 0 || len(s.DevBuf.Buf["Device"]) != 0 {
|
|
|
|
|
logging.Debug(logging.DClient,"Clearing buff %v", s.DevBuf.Buf)
|
|
|
|
|
}
|
|
|
|
|
for _, devs := range s.DevBuf.Buf {
|
|
|
|
|
for _, dev := range devs {
|
|
|
|
|
// loops over reactors then devices
|
|
|
|
@ -98,16 +101,18 @@ func (s *StatusMonitor) UpdateListener(tid, reactorId uint32) {
|
|
|
|
|
defer s.DevBuf.Unlock()
|
|
|
|
|
// clearing proper buffer
|
|
|
|
|
if reactorId == 0 {
|
|
|
|
|
s.DevBuf.Buf["Reactors"] = make(map[uint32]*DeviceInfo)
|
|
|
|
|
s.ReactorChan, s.DevBuf.Buf["Reactors"] = s.SystemViewer.AddListener(tid, reactorId)
|
|
|
|
|
logging.Debug(logging.DClient,"SYS 01 Adding %v as reactor listener", tid)
|
|
|
|
|
s.DevBuf.Buf["Reactor"] = make(map[uint32]*DeviceInfo)
|
|
|
|
|
s.ReactorChan, s.DevBuf.Buf["Reactor"] = s.SystemViewer.AddListener(tid, reactorId)
|
|
|
|
|
go s.Listen(s.ReactorChan)
|
|
|
|
|
} else {
|
|
|
|
|
s.DevBuf.Buf["Devices"] = make(map[uint32]*DeviceInfo) // clearing old devices
|
|
|
|
|
logging.Debug(logging.DClient,"SYS 01 Adding %v as reactor %v listener", tid, reactorId)
|
|
|
|
|
s.DevBuf.Buf["Device"] = make(map[uint32]*DeviceInfo) // clearing old devices
|
|
|
|
|
if s.DevBuf.ReactorId != reactorId && s.DevBuf.ReactorId != 0{
|
|
|
|
|
go s.SystemViewer.RemoveListener(s.DevBuf.ReactorId, tid)
|
|
|
|
|
}
|
|
|
|
|
s.DevBuf.ReactorId = reactorId
|
|
|
|
|
s.DevChan, s.DevBuf.Buf["Devices"] = s.SystemViewer.AddListener(tid, reactorId)
|
|
|
|
|
s.DevChan, s.DevBuf.Buf["Device"] = s.SystemViewer.AddListener(tid, reactorId)
|
|
|
|
|
go s.Listen(s.DevChan)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -115,19 +120,19 @@ func (s *StatusMonitor) UpdateListener(tid, reactorId uint32) {
|
|
|
|
|
func (s *StatusMonitor) UpdateBuffer(d *DeviceInfo, dtype string, ch chan *DeviceInfo) {
|
|
|
|
|
s.DevBuf.Lock()
|
|
|
|
|
defer s.DevBuf.Unlock()
|
|
|
|
|
logging.Debug(logging.DClient,"SYS 01 Dev %v update requested", d)
|
|
|
|
|
if dev, exists := s.DevBuf.Buf[dtype][d.Id]; exists {
|
|
|
|
|
// already a device in the buffer
|
|
|
|
|
fmt.Printf("Old: %v,\nNew: %v \n", dev, d)
|
|
|
|
|
if dev.TransactionId > d.TransactionId {
|
|
|
|
|
logging.Debug(logging.DClient,"SYS 01 Update Processed. Old: %v, New: %v \n", dev, d)
|
|
|
|
|
d = dev // not sure if i can do this lol
|
|
|
|
|
fmt.Printf("Old: %v,\nNew: %v \n", dev, d)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ch == s.ReactorChan || ch == s.DevChan {
|
|
|
|
|
// hacky way to check if the device came from a listener of a current channel
|
|
|
|
|
s.DevBuf.Buf[dtype][d.Id] = d
|
|
|
|
|
} else {
|
|
|
|
|
fmt.Printf("%v out of date\n",d)
|
|
|
|
|
logging.Debug(logging.DClient,"Dev out of date!")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -157,7 +162,6 @@ type listeners struct {
|
|
|
|
|
|
|
|
|
|
type lischan struct {
|
|
|
|
|
sync.WaitGroup
|
|
|
|
|
WaitChan chan struct{}
|
|
|
|
|
StatusChan chan *DeviceInfo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -167,6 +171,11 @@ type syslayout struct {
|
|
|
|
|
sync.RWMutex
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewLisChan(ch chan *DeviceInfo) *lischan {
|
|
|
|
|
l := &lischan{StatusChan:ch}
|
|
|
|
|
return l
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewInfoStream() *InfoStream {
|
|
|
|
|
dch := make(chan *DeviceInfo)
|
|
|
|
|
s := &InfoStream{Stream:dch}
|
|
|
|
@ -186,15 +195,14 @@ func (s *InfoStream) AddSender() chan *DeviceInfo {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *InfoStream) Listen() {
|
|
|
|
|
for {
|
|
|
|
|
deviceInfo := <-s.Stream
|
|
|
|
|
for deviceInfo := range s.Stream {
|
|
|
|
|
go s.Update(deviceInfo)
|
|
|
|
|
go s.Echo(deviceInfo)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *InfoStream) Update(d *DeviceInfo) {
|
|
|
|
|
s.Layout.Lock()
|
|
|
|
|
defer s.Layout.Unlock()
|
|
|
|
|
if dev, ok := s.Layout.Devs[d.Id]; !ok {
|
|
|
|
|
d.Index = s.Layout.uint32
|
|
|
|
|
s.Layout.uint32 += 1
|
|
|
|
@ -222,14 +230,15 @@ func (s *InfoStream) AddListener(id uint32, ch chan *DeviceInfo) map[uint32]*Dev
|
|
|
|
|
// if i get a memory leak ill eat my shoe
|
|
|
|
|
s.listeners.Lock()
|
|
|
|
|
defer s.listeners.Unlock()
|
|
|
|
|
if lis, ok := s.listeners.Listeners[id]; ok {
|
|
|
|
|
if _, ok := s.listeners.Listeners[id]; ok {
|
|
|
|
|
// exists
|
|
|
|
|
go lis.Exit()
|
|
|
|
|
delete(s.listeners.Listeners,id)
|
|
|
|
|
go s.RemoveListener(id)
|
|
|
|
|
}
|
|
|
|
|
s.listeners.Listeners[id] = &lischan{StatusChan:ch}
|
|
|
|
|
s.Layout.RLock()
|
|
|
|
|
defer s.Layout.RUnlock()
|
|
|
|
|
s.listeners.Listeners[id] = NewLisChan(ch)
|
|
|
|
|
logging.Debug(logging.DClient,"SYS 01 Getting Devices")
|
|
|
|
|
//s.Layout.RLock()
|
|
|
|
|
//defer s.Layout.RUnlock()
|
|
|
|
|
logging.Debug(logging.DClient,"SYS 01 Returning Devices %v", s.Layout.Devs)
|
|
|
|
|
return s.Layout.Devs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -237,26 +246,14 @@ func (l *listeners) RemoveListener(id uint32) {
|
|
|
|
|
l.Lock()
|
|
|
|
|
defer l.Unlock()
|
|
|
|
|
if lis, ok := l.Listeners[id]; ok {
|
|
|
|
|
go func(){
|
|
|
|
|
lis.Wait()
|
|
|
|
|
close(lis.WaitChan)
|
|
|
|
|
}()
|
|
|
|
|
go lis.Exit()
|
|
|
|
|
delete(l.Listeners,id)
|
|
|
|
|
go func(ls *lischan){
|
|
|
|
|
ls.Wait()
|
|
|
|
|
close(ls.StatusChan)
|
|
|
|
|
}(lis)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (l *lischan) Exit() {
|
|
|
|
|
for {
|
|
|
|
|
select {
|
|
|
|
|
case <-l.WaitChan:
|
|
|
|
|
close(l.StatusChan)
|
|
|
|
|
break;
|
|
|
|
|
case <-l.StatusChan:
|
|
|
|
|
// dump buffer
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// status buffer maintaince
|
|
|
|
|
|
|
|
|
|
type SystemViewer struct {
|
|
|
|
@ -309,7 +306,7 @@ func (s *SystemViewer) AddListener(id, rid uint32) (chan *DeviceInfo, map[uint32
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *SystemViewer) RemoveListener(tid, rid uint32) {
|
|
|
|
|
func (s *SystemViewer) RemoveListener(rid, tid uint32) {
|
|
|
|
|
// removes chan for specific tid and rid
|
|
|
|
|
s.DeviceStream.Lock()
|
|
|
|
|
defer s.DeviceStream.Unlock()
|
|
|
|
|