diff --git a/controller/monitor.go b/controller/monitor.go index 4511e5a..1e5c90a 100644 --- a/controller/monitor.go +++ b/controller/monitor.go @@ -58,7 +58,7 @@ type appMon struct { app *App done chan bool announced bool - checkOn bool + runLoopOn bool } // MonitorMgr manages the lifecycle of registered apps @@ -154,11 +154,12 @@ func (m *MonitorMgr) consulMon() { func (m *MonitorMgr) Add(app *App) { // check if already running m.monMu.Lock() + var existing *appMon for _, appMon := range m.monitors { - if appMon.app.Equal(app) && appMon.checkOn { - glog.V(2).Infof("App %s already exists", app.Name) - m.monMu.Unlock() - return + if appMon.app.Equal(app) { + glog.Infof("App %s already exists", app.Name) + existing = appMon + break } if appMon.app.Vip.Net.String() == app.Vip.Net.String() && appMon.app.Name != app.Name { glog.Errorf("Error: Vip %s is already being announced by app: %s", app.Vip.Net.String(), appMon.app.Name) @@ -167,11 +168,19 @@ func (m *MonitorMgr) Add(app *App) { } } m.monMu.Unlock() - m.Remove(app.Name) - appMon := &appMon{app: app, done: make(chan bool)} - m.monitors[app.Name] = appMon - go m.runLoop(appMon) - glog.Infof("Registered a new app: %v", app.String()) + // if the same app already exists but its run loop is not running, + // then just restart the run loop + if existing != nil { + if !existing.runLoopOn { + go m.runLoop(existing) + } + } else { + // else add a new app and start its run loop + appMon := &appMon{app: app, done: make(chan bool)} + m.monitors[app.Name] = appMon + go m.runLoop(appMon) + glog.Infof("Registered a new app: %v", app.String()) + } } // Remove removes an app from monitor manager, stops BGP @@ -180,7 +189,7 @@ func (m *MonitorMgr) Remove(appName string) { m.monMu.Lock() defer m.monMu.Unlock() if a, ok := m.monitors[appName]; ok { - if a.checkOn { + if a.runLoopOn { close(a.done) } if a.announced { @@ -272,7 +281,8 @@ func (m *MonitorMgr) checkCond(am *appMon) error { // runLoop periodically checks if an app passes healthchecks // and needs VIP announcement func (m *MonitorMgr) runLoop(am *appMon) { - am.checkOn = true + glog.Infof("Starting run-loop for app %s", am.app.Name) + am.runLoopOn = true if err := m.checkCond(am); err != nil { glog.Errorln(err) } @@ -285,8 +295,8 @@ func (m *MonitorMgr) runLoop(am *appMon) { glog.Errorln(err) } case <-am.done: - glog.V(2).Infof("Exit run-loop for app: %s", am.app.Name) - am.checkOn = false + glog.Infof("Exit run-loop for app: %s", am.app.Name) + am.runLoopOn = false return } } @@ -299,7 +309,7 @@ func (m *MonitorMgr) CloseAll() { glog.Errorf("Failed to shut-down BGP: %v", err) } for _, am := range m.monitors { - if am.checkOn { + if am.runLoopOn { close(am.done) } deleteLoopback(am.app.Vip.Net)