gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/lifecycle/interrupted-starter.go (about) 1 package lifecycle 2 3 import ( 4 "gitee.com/sy_183/go-common/chans" 5 ) 6 7 type InterruptedStarter interface { 8 DoStart(lifecycle Lifecycle, interrupter chan struct{}) (runFn InterruptedRunFunc, err error) 9 } 10 11 type InterruptedStarterFunc = func(lifecycle Lifecycle, interrupter chan struct{}) (runFn InterruptedRunFunc, err error) 12 13 type interruptedStarterFunc InterruptedStarterFunc 14 15 func FuncInterruptedStarter(starterFn InterruptedStarterFunc) InterruptedStarter { 16 if starterFn == nil { 17 starterFn = func(lifecycle Lifecycle, interrupter chan struct{}) (runFn InterruptedRunFunc, err error) { 18 return nil, nil 19 } 20 } 21 return interruptedStarterFunc(starterFn) 22 } 23 24 func (f interruptedStarterFunc) DoStart(lifecycle Lifecycle, interrupter chan struct{}) (runFn InterruptedRunFunc, err error) { 25 return f(lifecycle, interrupter) 26 } 27 28 type interruptedStarter struct { 29 canInterrupted canInterrupted 30 interrupter chan struct{} 31 starter InterruptedStarter 32 runFn InterruptedRunFunc 33 } 34 35 func newInterruptedStarter(canInterrupted canInterrupted, starter InterruptedStarter) *interruptedStarter { 36 return &interruptedStarter{ 37 canInterrupted: canInterrupted, 38 interrupter: make(chan struct{}, 1), 39 starter: starter, 40 } 41 } 42 43 func (s *interruptedStarter) Runner() Runner { 44 return FuncRunner(s.start, nil, s.close) 45 } 46 47 func (s *interruptedStarter) RunningRunner() Runner { 48 return FuncRunner(nil, s.run, s.close) 49 } 50 51 func (s *interruptedStarter) start(lifecycle Lifecycle) (err error) { 52 runFn, err := s.starter.DoStart(lifecycle, s.interrupter) 53 if err != nil { 54 chans.TryPop(s.interrupter) 55 return err 56 } 57 s.runFn = runFn 58 s.canInterrupted.setRunner(s.RunningRunner()) 59 return nil 60 } 61 62 func (s *interruptedStarter) run(lifecycle Lifecycle) (err error) { 63 defer chans.TryPop(s.interrupter) 64 defer s.canInterrupted.setRunner(s.Runner()) 65 if s.runFn != nil { 66 return s.runFn(lifecycle, s.interrupter) 67 } 68 return nil 69 } 70 71 func (s *interruptedStarter) close(Lifecycle) error { 72 s.canInterrupted.ToClosing() 73 s.interrupter <- struct{}{} 74 return nil 75 }