gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/lifecycle/child.go (about)

     1  package lifecycle
     2  
     3  import (
     4  	"gitee.com/sy_183/go-common/chans"
     5  	"gitee.com/sy_183/go-common/container"
     6  	"gitee.com/sy_183/go-common/lock"
     7  	"sync"
     8  )
     9  
    10  type childLifecycleContext[L any] struct {
    11  	Lifecycle L
    12  	channel   *childLifecycleChannel[L]
    13  	err       error
    14  }
    15  
    16  func (c childLifecycleContext[L]) Clone(err error) (nc childLifecycleContext[L]) {
    17  	nc = c
    18  	nc.err = err
    19  	return
    20  }
    21  
    22  func (c childLifecycleContext[L]) Complete(err error) {
    23  	c.channel.Push(c.Clone(err))
    24  }
    25  
    26  type childLifecycleChannel[L any] struct {
    27  	signal   chan struct{}
    28  	contexts *container.LinkedList[childLifecycleContext[L]]
    29  	mu       sync.Mutex
    30  }
    31  
    32  func newChildLifecycleChannel[L any]() *childLifecycleChannel[L] {
    33  	return &childLifecycleChannel[L]{
    34  		signal:   make(chan struct{}, 1),
    35  		contexts: container.NewLinkedList[childLifecycleContext[L]](0),
    36  	}
    37  }
    38  
    39  func (c *childLifecycleChannel[L]) Signal() <-chan struct{} {
    40  	return c.signal
    41  }
    42  
    43  func (c *childLifecycleChannel[L]) Push(ctx childLifecycleContext[L]) {
    44  	lock.LockDo(&c.mu, func() {
    45  		c.contexts.Push(ctx)
    46  	})
    47  	chans.TryPush(c.signal, struct{}{})
    48  }
    49  
    50  func (c *childLifecycleChannel[L]) Pop() []childLifecycleContext[L] {
    51  	return lock.LockGet(&c.mu, func() []childLifecycleContext[L] {
    52  		contexts := make([]childLifecycleContext[L], 0, c.contexts.Len())
    53  		for entry := c.contexts.HeadEntry(); entry != nil; entry = entry.Next() {
    54  			contexts = append(contexts, entry.Value())
    55  		}
    56  		c.contexts.Clear()
    57  		return contexts
    58  	})
    59  }