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  }