gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/lifecycle/interrupted-runner.go (about) 1 package lifecycle 2 3 import ( 4 "gitee.com/sy_183/go-common/chans" 5 ) 6 7 type InterruptedRunner interface { 8 DoStart(lifecycle Lifecycle, interrupter chan struct{}) error 9 10 DoRun(lifecycle Lifecycle, interrupter chan struct{}) error 11 } 12 13 type ( 14 InterruptedStartFunc = func(lifecycle Lifecycle, interrupter chan struct{}) error 15 InterruptedRunFunc = func(lifecycle Lifecycle, interrupter chan struct{}) error 16 ) 17 18 func InterrupterHoldRun(_ Lifecycle, interrupter chan struct{}) error { 19 <-interrupter 20 return nil 21 } 22 23 type interruptedRunnerFunc struct { 24 startFn InterruptedStartFunc 25 runFn InterruptedRunFunc 26 } 27 28 func FuncInterruptedRunner(startFn InterruptedStartFunc, runFn InterruptedRunFunc) InterruptedRunner { 29 if startFn == nil { 30 startFn = func(lifecycle Lifecycle, interrupter chan struct{}) error { return nil } 31 } 32 if runFn == nil { 33 runFn = func(lifecycle Lifecycle, interrupter chan struct{}) error { return nil } 34 } 35 return interruptedRunnerFunc{startFn: startFn, runFn: runFn} 36 } 37 38 func (f interruptedRunnerFunc) DoStart(lifecycle Lifecycle, interrupter chan struct{}) error { 39 return f.startFn(lifecycle, interrupter) 40 } 41 42 func (f interruptedRunnerFunc) DoRun(lifecycle Lifecycle, interrupter chan struct{}) error { 43 return f.runFn(lifecycle, interrupter) 44 } 45 46 type canInterrupted interface { 47 setRunner(runner Runner) 48 ToClosing() 49 } 50 51 type interruptedRunner struct { 52 canInterrupted canInterrupted 53 interrupter chan struct{} 54 runner InterruptedRunner 55 } 56 57 func newInterrupterRunner(canInterrupted canInterrupted, runner InterruptedRunner) *interruptedRunner { 58 return &interruptedRunner{ 59 canInterrupted: canInterrupted, 60 interrupter: make(chan struct{}, 1), 61 runner: runner, 62 } 63 } 64 65 func (r *interruptedRunner) DoStart(lifecycle Lifecycle) error { 66 err := r.runner.DoStart(lifecycle, r.interrupter) 67 if err != nil { 68 chans.TryPop(r.interrupter) 69 } 70 return err 71 } 72 73 func (r *interruptedRunner) DoRun(lifecycle Lifecycle) error { 74 defer chans.TryPop(r.interrupter) 75 return r.runner.DoRun(lifecycle, r.interrupter) 76 } 77 78 func (r *interruptedRunner) DoClose(Lifecycle) error { 79 r.canInterrupted.ToClosing() 80 r.interrupter <- struct{}{} 81 return nil 82 }