func doRun() int { slog.Colorized("{green}Starting {yellow}Z{red}e{blue}u{magenta}s{green} server") zerror.Init() var tree *processtree.ProcessTree = config.BuildProcessTree() done := make(chan bool) // Start processes and register them for exit when the function returns. filesChanged, filemonitorDone := filemonitor.Start(done) defer exit(processtree.StartSlaveMonitor(tree, done), done) defer exit(clienthandler.Start(tree, done), done) defer exit(filemonitorDone, done) defer slog.Suppress() defer zerror.PrintFinalOutput() defer exit(statuschart.Start(tree, done), done) c := make(chan os.Signal, 1) signal.Notify(c, terminatingSignals...) for { select { case sig := <-c: if sig == syscall.SIGINT { return 0 } else { return 1 } case changed := <-filesChanged: go tree.RestartNodesWithFeature(changed) } } return -1 // satisfy the compiler }
// Collect file changes that happen FileChangeWindow ms from each // other, and restart all nodes in the process tree that match // features of the changed files. func start(tree *processtree.ProcessTree, filesChanged chan string, done, quit chan bool) { for { select { case <-quit: done <- true return case file := <-filesChanged: changed := make(map[string]bool) changed[file] = true slog.Trace("Restarter got the first file of potentially many") deadline := time.After(FileChangeWindow) deadline_expired := false for !deadline_expired { select { case <-quit: done <- true return case file := <-filesChanged: changed[file] = true case <-deadline: deadline_expired = true } } slog.Trace("Restarter has gathered %d changed files", len(changed)) go tree.RestartNodesWithFeatures(changed) } } }
func findCommandAndSlaveNodes(tree *processtree.ProcessTree, command string, err error) (*processtree.CommandNode, *processtree.SlaveNode, error) { if err != nil { return nil, nil, err } commandNode := tree.FindCommand(command) if commandNode == nil { return nil, nil, errors.New("ERROR: Node not found!: " + command) } command = commandNode.Name slaveNode := commandNode.Parent return commandNode, slaveNode, nil }
func iteratePlan(tree *processtree.ProcessTree, plan map[string]interface{}, parent *processtree.SlaveNode) { for name, v := range plan { if subPlan, ok := v.(map[string]interface{}); ok { newNode := tree.NewSlaveNode(name, parent) if parent == nil { tree.Root = newNode } else { parent.Slaves = append(parent.Slaves, newNode) } iteratePlan(tree, subPlan, newNode) } else { var newNode *processtree.CommandNode if aliases, ok := v.([]interface{}); ok { strs := make([]string, len(aliases)) for i, alias := range aliases { strs[i] = alias.(string) } newNode = tree.NewCommandNode(name, strs, parent) } else if v == nil { newNode = tree.NewCommandNode(name, nil, parent) } else { zerror.ErrorConfigFileInvalidFormat() } parent.Commands = append(parent.Commands, newNode) } } }