gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/lifecycle.v2/interrupted.go (about) 1 package lifecycle 2 3 import ( 4 "errors" 5 "sync/atomic" 6 ) 7 8 var ErrInterrupted = errors.New("interrupted") 9 10 type InterruptedRunner interface { 11 DoStart(lifecycle Lifecycle, interrupter chan struct{}) error 12 13 DoRun(lifecycle Lifecycle, interrupter chan struct{}) error 14 } 15 16 type ( 17 InterruptedStartFunc = func(lifecycle Lifecycle, interrupter chan struct{}) error 18 InterruptedRunFunc = func(lifecycle Lifecycle, interrupter chan struct{}) error 19 ) 20 21 type interruptedRunnerFunc struct { 22 startFn InterruptedStartFunc 23 runFn InterruptedRunFunc 24 } 25 26 func FuncInterruptedRunner(startFn InterruptedStartFunc, runFn InterruptedRunFunc) InterruptedRunner { 27 if startFn == nil { 28 startFn = func(lifecycle Lifecycle, interrupter chan struct{}) error { return nil } 29 } 30 if runFn == nil { 31 runFn = func(lifecycle Lifecycle, interrupter chan struct{}) error { return nil } 32 } 33 return interruptedRunnerFunc{startFn: startFn, runFn: runFn} 34 } 35 36 func (f interruptedRunnerFunc) DoStart(lifecycle Lifecycle, interrupter chan struct{}) error { 37 return f.startFn(lifecycle, interrupter) 38 } 39 40 func (f interruptedRunnerFunc) DoRun(lifecycle Lifecycle, interrupter chan struct{}) error { 41 return f.runFn(lifecycle, interrupter) 42 } 43 44 type onceInterrupter struct { 45 interrupter chan struct{} 46 interrupted atomic.Bool 47 } 48 49 func (i *onceInterrupter) Interrupted() bool { 50 return i.interrupted.Load() 51 } 52 53 func (i *onceInterrupter) DoClose(Lifecycle) error { 54 if i.interrupted.CompareAndSwap(false, true) { 55 i.interrupter <- struct{}{} 56 } 57 return nil 58 } 59 60 type interruptedRunner struct { 61 onceInterrupter 62 runner InterruptedRunner 63 } 64 65 func WrapInterruptedRunner(runner InterruptedRunner) Runner { 66 return &interruptedRunner{ 67 onceInterrupter: onceInterrupter{ 68 interrupter: make(chan struct{}, 1), 69 }, 70 runner: runner, 71 } 72 } 73 74 func (r *interruptedRunner) DoStart(lifecycle Lifecycle) error { 75 return r.runner.DoStart(lifecycle, r.interrupter) 76 } 77 78 func (r *interruptedRunner) DoRun(lifecycle Lifecycle) error { 79 return r.runner.DoRun(lifecycle, r.interrupter) 80 } 81 82 type InterruptedStarter interface { 83 DoStart(lifecycle Lifecycle, interrupter chan struct{}) (runFn InterruptedRunFunc, err error) 84 } 85 86 type InterruptedStarterFunc = func(lifecycle Lifecycle, interrupter chan struct{}) (runFn InterruptedRunFunc, err error) 87 88 type interruptedStarterFunc InterruptedStarterFunc 89 90 func FuncInterruptedStarter(starterFn InterruptedStarterFunc) InterruptedStarter { 91 if starterFn == nil { 92 starterFn = func(lifecycle Lifecycle, interrupter chan struct{}) (runFn InterruptedRunFunc, err error) { 93 return nil, nil 94 } 95 } 96 return interruptedStarterFunc(starterFn) 97 } 98 99 func (f interruptedStarterFunc) DoStart(lifecycle Lifecycle, interrupter chan struct{}) (runFn InterruptedRunFunc, err error) { 100 return f(lifecycle, interrupter) 101 } 102 103 type interruptedStarterRunner struct { 104 onceInterrupter 105 starter InterruptedStarter 106 runFn InterruptedRunFunc 107 } 108 109 func InterruptedStarterRunner(starter InterruptedStarter) Runner { 110 return &interruptedStarterRunner{ 111 onceInterrupter: onceInterrupter{ 112 interrupter: make(chan struct{}, 1), 113 }, 114 starter: starter, 115 } 116 } 117 118 func (r *interruptedStarterRunner) DoStart(lifecycle Lifecycle) error { 119 runFn, err := r.starter.DoStart(lifecycle, r.interrupter) 120 if err != nil { 121 return err 122 } 123 r.runFn = runFn 124 return nil 125 } 126 127 func (r *interruptedStarterRunner) DoRun(lifecycle Lifecycle) error { 128 if r.runFn != nil { 129 return r.runFn(lifecycle, r.interrupter) 130 } 131 return nil 132 }