github.com/helmwave/helmwave@v0.36.4-0.20240509190856-b35563eba4c6/pkg/release/dependency/node.go (about)

     1  package dependency
     2  
     3  import "sync"
     4  
     5  const (
     6  	// NodePending is a NodeStatus for pending node.
     7  	NodePending NodeStatus = iota
     8  
     9  	// NodeSuccess is a NodeStatus for success node.
    10  	NodeSuccess
    11  
    12  	// NodeFailed is a NodeStatus for failed node.
    13  	NodeFailed
    14  )
    15  
    16  // NodeStatus is used to code release status - success or failed.
    17  // Please use ReleaseSuccess and ReleaseFailed contants.
    18  type NodeStatus int
    19  
    20  // Node is graph node. N stands for data type.
    21  type Node[N any] struct {
    22  	Data         N
    23  	dependencies []*Node[N]
    24  	lock         sync.RWMutex
    25  	status       NodeStatus
    26  }
    27  
    28  func newNode[N any](data N) *Node[N] {
    29  	return &Node[N]{
    30  		Data:         data,
    31  		status:       NodePending,
    32  		dependencies: make([]*Node[N], 0),
    33  	}
    34  }
    35  
    36  func (node *Node[N]) SetSucceeded() {
    37  	node.lock.Lock()
    38  	defer node.lock.Unlock()
    39  
    40  	node.status = NodeSuccess
    41  }
    42  
    43  func (node *Node[N]) SetFailed() {
    44  	node.lock.Lock()
    45  	defer node.lock.Unlock()
    46  
    47  	node.status = NodeFailed
    48  }
    49  
    50  func (node *Node[N]) IsDone() bool {
    51  	node.lock.RLock()
    52  	defer node.lock.RUnlock()
    53  
    54  	return node.status != NodePending
    55  }
    56  
    57  func (node *Node[N]) IsFailed() bool {
    58  	node.lock.RLock()
    59  	defer node.lock.RUnlock()
    60  
    61  	return node.status == NodeFailed
    62  }
    63  
    64  func (node *Node[N]) IsReady() bool {
    65  	node.lock.RLock()
    66  	deps := node.dependencies
    67  	node.lock.RUnlock()
    68  
    69  	for _, dependency := range deps {
    70  		if !dependency.IsDone() {
    71  			return false
    72  		}
    73  
    74  		if dependency.IsFailed() {
    75  			node.SetFailed()
    76  
    77  			return false
    78  		}
    79  	}
    80  
    81  	return true
    82  }
    83  
    84  func (node *Node[N]) addDependency(dependency *Node[N]) {
    85  	node.lock.Lock()
    86  	defer node.lock.Unlock()
    87  
    88  	node.dependencies = append(node.dependencies, dependency)
    89  }