github.com/nycdavid/zeus@v0.0.0-20201208104106-9ba439429e03/go/processtree/processtree.go (about) 1 package processtree 2 3 import ( 4 "sync" 5 ) 6 7 type ProcessTree struct { 8 Root *SlaveNode 9 ExecCommand string 10 SlavesByName map[string]*SlaveNode 11 Commands []*CommandNode 12 StateChanged chan bool 13 } 14 15 type ProcessTreeNode struct { 16 mu sync.RWMutex 17 Parent *SlaveNode 18 Name string 19 } 20 21 type CommandNode struct { 22 ProcessTreeNode 23 booting sync.RWMutex 24 Aliases []string 25 } 26 27 func (tree *ProcessTree) NewCommandNode(name string, aliases []string, parent *SlaveNode) *CommandNode { 28 x := &CommandNode{} 29 x.Parent = parent 30 x.Name = name 31 x.Aliases = aliases 32 tree.Commands = append(tree.Commands, x) 33 return x 34 } 35 36 func (tree *ProcessTree) FindSlaveByName(name string) *SlaveNode { 37 if name == "" { 38 return tree.Root 39 } 40 return tree.SlavesByName[name] 41 } 42 43 func (tree *ProcessTree) FindCommand(requested string) *CommandNode { 44 for _, command := range tree.Commands { 45 if command.Name == requested { 46 return command 47 } 48 for _, alias := range command.Aliases { 49 if alias == requested { 50 return command 51 } 52 } 53 } 54 return nil 55 } 56 57 func (tree *ProcessTree) AllCommandsAndAliases() []string { 58 var values []string 59 for _, command := range tree.Commands { 60 values = append(values, command.Name) 61 for _, alias := range command.Aliases { 62 values = append(values, alias) 63 } 64 } 65 return values 66 } 67 68 var restartMutex sync.Mutex 69 70 func (tree *ProcessTree) RestartNodesWithFeatures(files []string) { 71 restartMutex.Lock() 72 defer restartMutex.Unlock() 73 tree.Root.trace("%d files changed, beginning with %q", len(files), files[0]) 74 tree.Root.restartNodesWithFeatures(tree, files) 75 } 76 77 // Serialized: restartMutex is always held when this is called. 78 func (node *SlaveNode) restartNodesWithFeatures(tree *ProcessTree, files []string) { 79 for _, file := range files { 80 if node.HasFeature(file) { 81 node.trace("restarting for %q", file) 82 node.RequestRestart() 83 return 84 } 85 } 86 for _, s := range node.Slaves { 87 s.restartNodesWithFeatures(tree, files) 88 } 89 } 90 91 // We implement sort.Interface - Len, Less, and Swap - on list of commands so 92 // we can use the sort package’s generic Sort function. 93 type Commands []*CommandNode 94 95 func (c Commands) Len() int { 96 return len(c) 97 } 98 99 func (c Commands) Swap(i, j int) { 100 c[i], c[j] = c[j], c[i] 101 } 102 103 func (c Commands) Less(i, j int) bool { 104 return c[i].Name < c[j].Name 105 }