func (handler *Handler) OnStart(container *docker.Container, exit *chan string) error { configCenter := appconfig.AppConfigCenter() app, appErr := configCenter.GetDaemonApp(container) if appErr != nil { return appErr } count := 1 var interval time.Duration if app.StartAwait != 0 { count = 3 interval = time.Duration(app.StartAwait/count) * time.Second } log.Printf("Start await: total %ds, retry %d, interval %ds", app.StartAwait, count, interval/time.Second) var valiErr error for i := 0; i < count; i++ { time.Sleep(interval) valiErr = app.Validate() if valiErr == nil { break } } if valiErr != nil { return valiErr } client := backends.ZKClient() if err := client.NewNode(app.NodePath(), app.Node); err != nil { return err } go app.WatchTillDie(exit) return nil }
func (app *DaemonApplication) WatchTillDie(exit *chan string) { client := backends.ZKClient() interval := time.Duration(app.HealthCheckInterval()) * time.Second retry := 0 for { select { case <-*exit: log.Printf("Container %s dead.", app.IpAddress) if err := client.RemoveNode(app.NodePath()); err != nil { log.Println("Error on quit:", err) continue } return case <-time.After(interval): if err := app.Validate(); err != nil && retry >= app.HealthCheckRetry() { if err := client.RemoveNode(app.NodePath()); err != nil { log.Println("Error on quit:", err) continue } return } else if err != nil { retry += 1 log.Printf("Retried %d on %s", retry, app.IpAddress) } } } }
func main() { wg := sync.WaitGroup{} client := backends.ZKClient() quitChan := make(map[string]*chan string) for _, appId := range config.Applications { quit := make(chan string) wg.Add(1) go func(appId string) { defer wg.Done() client.Watch(appId, &Handler{}, &quit) }(appId) quitChan[appId] = &quit } c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGHUP) s := <-c if s != syscall.SIGHUP { for _, quit := range quitChan { *quit <- "quit" } signal.Stop(c) wg.Wait() os.Exit(0) } else { warden.ReloadGuardianSettings() } }
func main() { daemonWatcher, daemonError := watcher.NewDaemonWatcher(config.DockerSocket) if daemonError != nil { log.Fatal(daemonError) } watcherExit := make(chan string) wg := sync.WaitGroup{} c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGHUP) client := backends.ZKClient() inited := false for { select { case s := <-c: if s != syscall.SIGHUP { watcherExit <- "quit" signal.Stop(c) wg.Wait() os.Exit(0) } else { warden.ReloadAgentSettings() } case event := <-client.EventChan: if event.State == zk.StateHasSession { log.Println("Load for new zk session") if inited { watcherExit <- "quit" } syncErr := daemonWatcher.SyncContainers(&Handler{}) if syncErr != nil { log.Fatal(syncErr) } wg.Add(1) go func() { defer wg.Done() daemonWatcher.Watch(&Handler{}, &watcherExit) }() inited = true } default: } } }