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 }