From 7b6cc0eb1d6d8e2a7fa22ade10e79eb06f0d6bbf Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Mon, 18 Apr 2016 23:58:07 +0200 Subject: fetch state from switch and server if they are stale/missing diff --git a/src/rhctl/audio_switch.go b/src/rhctl/audio_switch.go index 8c698b4..dd61f46 100644 --- a/src/rhctl/audio_switch.go +++ b/src/rhctl/audio_switch.go @@ -85,9 +85,10 @@ type SwitchState struct { Inputs [SwitchInputNumMax]bool Silence bool } - GPI [SwitchGPINumMax]bool - Relay [SwitchRelayNumMax]bool - OC [SwitchOCNumMax]bool + GPI [SwitchGPINumMax]bool + Relay [SwitchRelayNumMax]bool + OC [SwitchOCNumMax]bool + Changed time.Time } type AudioSwitch struct { @@ -127,6 +128,7 @@ func (sw *AudioSwitch) updateStateAudio(data string) { rhl.Printf("Audioswitch: invalid audio status update (state must be either '1' or '0' but is '%s')", ins[i]) } } + sw.state.Changed = time.Now() sw.StateChanges <- sw.state } @@ -152,6 +154,7 @@ func (sw *AudioSwitch) updateStateGPI(data string) { rhl.Printf("Audioswitch: invalid gpi status update (state must be either '1' or '0' but is '%s')", data[7:8]) return } + sw.state.Changed = time.Now() sw.StateChanges <- sw.state return } @@ -177,6 +180,7 @@ func (sw *AudioSwitch) updateStateGPI(data string) { rhl.Printf("Audioswitch: invalid gpi status update (state must be either '1' or '0' but is '%s')", ins[i]) } } + sw.state.Changed = time.Now() sw.StateChanges <- sw.state } @@ -201,6 +205,7 @@ func (sw *AudioSwitch) updateStateRelay(data string) { rhl.Printf("Audioswitch: invalid relay status update (state must be either '1' or '0' but is '%s')", outs[i]) } } + sw.state.Changed = time.Now() sw.StateChanges <- sw.state } @@ -225,6 +230,7 @@ func (sw *AudioSwitch) updateStateOC(data string) { rhl.Printf("Audioswitch: invalid oc status update (state must be either '1' or '0' but is '%s')", outs[i]) } } + sw.state.Changed = time.Now() sw.StateChanges <- sw.state } @@ -249,6 +255,7 @@ func (sw *AudioSwitch) updateStateSilence(data string) { rhl.Printf("Audioswitch: invalid silence status update (state must be either '1' or '0' but is '%s')", outs[i]) } } + sw.state.Changed = time.Now() sw.StateChanges <- sw.state } @@ -261,12 +268,14 @@ func (sw *AudioSwitch) handleData(data string) { rhdl.Printf("Audioswitch: got data: %q", data) if data[0:3] == "RRR" || data[0:3] == "EEE" { if sw.current != nil { - resp := SwitchResponse{Message: data} - resp.Result = SwitchError - if data[0] == 'R' { - resp.Result = SwitchOK + if sw.current.Response != nil { + resp := SwitchResponse{Message: data} + resp.Result = SwitchError + if data[0] == 'R' { + resp.Result = SwitchOK + } + sw.current.Response <- resp } - sw.current.Response <- resp sw.current = nil sw.timer.Stop() sw.timer = nil @@ -313,7 +322,9 @@ func (sw *AudioSwitch) Run() { case <-stop: return case <-sw.timer.C: - sw.current.Response <- fmt.Errorf("command timed out") + if sw.current.Response != nil { + sw.current.Response <- fmt.Errorf("command timed out") + } sw.current = nil sw.timer = nil case data := <-sw.port.rx: @@ -326,7 +337,9 @@ func (sw *AudioSwitch) Run() { case cmd := <-sw.Commands: c, err := cmd.Cmd.Generate(append(cmd.Args, sw.unit)...) if err != nil { - cmd.Response <- err + if cmd.Response != nil { + cmd.Response <- err + } } else { rhdl.Printf("sending '%s' to switch", c) sw.current = cmd @@ -348,7 +361,7 @@ func SwitchInit(conf *Config) (sw *AudioSwitch, err error) { } sw.unit = conf.Audioswitch.Unit sw.StateChanges = make(chan SwitchState, 16) - sw.Commands = make(chan *SwitchCommand, 8) + sw.Commands = make(chan *SwitchCommand, 16) sw.Updates = make(chan SwitchUpdate, 32) if sw.port, err = SerialOpen(conf.Audioswitch.Device, conf.Audioswitch.Baudrate, ""); err != nil { diff --git a/src/rhctl/playout_server.go b/src/rhctl/playout_server.go index ca00611..30577b8 100644 --- a/src/rhctl/playout_server.go +++ b/src/rhctl/playout_server.go @@ -48,6 +48,7 @@ type ServerState struct { Name string Health ServerHealth Channel string + Changed time.Time } type PlayoutServer struct { @@ -73,6 +74,7 @@ func (srv *PlayoutServer) handleControl(data string) { return } srv.state.Channel = data[8:] + srv.state.Changed = time.Now() srv.StateChanges <- srv.state return } @@ -89,6 +91,7 @@ func (srv *PlayoutServer) handleHeartbeat(data string) { old := srv.state.Health srv.state.Health = ServerAlive + srv.state.Changed = time.Now() if old != srv.state.Health { srv.StateChanges <- srv.state rhl.Printf("Server(%s): is back from the dead!", srv.name) @@ -102,6 +105,7 @@ func (srv *PlayoutServer) handleHBTimeout() { rhl.Printf("Server(%s): heartbeat timed-out", srv.name) srv.hbcnt = 0 srv.state.Health = ServerDead + srv.state.Changed = time.Now() srv.StateChanges <- srv.state } diff --git a/src/rhctl/switch_control.go b/src/rhctl/switch_control.go index 2864cc9..caee99b 100644 --- a/src/rhctl/switch_control.go +++ b/src/rhctl/switch_control.go @@ -23,6 +23,7 @@ package main import ( "fmt" + "time" "github.com/btittelbach/pubsub" ) @@ -125,7 +126,20 @@ func handleServer(in <-chan ServerState, out chan<- ServerState) { func (ctrl *SwitchControl) reconcile(requestedServer string) (result bool) { rhdl.Printf("SwitchCTRL: reconciling state... (requested server: '%s')", requestedServer) - // TODO: set mood dependent on overall-state + if time.Since(ctrl.state.Switch.Changed) > (2 * time.Hour) { // TODO: hardcoded value + ctrl.sw.Commands <- &SwitchCommand{SwitchCmdStateAudio, nil, nil} + ctrl.sw.Commands <- &SwitchCommand{SwitchCmdStateGPIAll, nil, nil} + ctrl.sw.Commands <- &SwitchCommand{SwitchCmdStateOC, nil, nil} + ctrl.sw.Commands <- &SwitchCommand{SwitchCmdStateRelay, nil, nil} + ctrl.sw.Commands <- &SwitchCommand{SwitchCmdStateSilence, nil, nil} + } + + for _, server := range ctrl.servers { + s, exists := ctrl.state.Server[server.name] + if !exists || time.Since(s.Changed) > (2*time.Hour) { // TODO: hardcoded value + server.UpdateRequest <- true + } + } // TODO: send out commands to switch and/or server to get missing infos @@ -133,6 +147,8 @@ func (ctrl *SwitchControl) reconcile(requestedServer string) (result bool) { // return true if requested server got selected // TODO: change switch output mappings if servers change channels or fail + + // TODO: set mood dependent on overall-state return } -- cgit v0.10.2