gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/lifecycle.v2/lifecycle.go (about) 1 package lifecycle 2 3 import ( 4 "gitee.com/sy_183/go-common/lifecycle.v2/future" 5 "sync/atomic" 6 "unsafe" 7 ) 8 9 type FutureType uint 10 11 const ( 12 FutureTypeStarted = FutureType(iota) 13 FutureTypeClosed = FutureType(iota) 14 futureTypes 15 ) 16 17 type Future future.Future[error] 18 19 type BeforeCallbackType uint 20 21 const ( 22 BeforeStart = BeforeCallbackType(iota) 23 BeforeClose 24 beforeCallbackTypes 25 ) 26 27 type AfterCallbackType uint 28 29 const ( 30 AfterStart = AfterCallbackType(iota) 31 AfterClose 32 AfterRun 33 afterCallbackTypes 34 ) 35 36 type PanicCallbackType uint 37 38 const ( 39 PanicOnStarting = PanicCallbackType(iota) 40 PanicOnRunning 41 panicCallbackTypes 42 ) 43 44 type ( 45 BeforeCallback = func(Lifecycle) error 46 AfterCallback = func(Lifecycle, error) 47 PanicCallback = func(Lifecycle, any) error 48 ) 49 50 type atomicEntry[V any] struct { 51 value V 52 next atomic.Pointer[atomicEntry[V]] 53 } 54 55 type atomicList[V any] struct { 56 head *atomicEntry[V] 57 tail atomic.Pointer[atomicEntry[V]] 58 } 59 60 func (l *atomicList[V]) init() { 61 l.head = new(atomicEntry[V]) 62 l.tail.Store(l.head) 63 } 64 65 func (l *atomicList[V]) append(v V) *atomicEntry[V] { 66 e := &atomicEntry[V]{value: v} 67 for { 68 tail := l.tail.Load() 69 if tail.next.CompareAndSwap(nil, e) { 70 l.tail.Store(e) 71 return e 72 } 73 } 74 } 75 76 type onceFuture struct { 77 future.Future[error] 78 once atomic.Bool 79 next atomic.Pointer[onceFuture] 80 } 81 82 func (f *onceFuture) Complete(err error) { 83 if f.once.CompareAndSwap(false, true) { 84 f.Future.Complete(err) 85 } 86 } 87 88 type onceFutures struct { 89 head *onceFuture 90 tail atomic.Pointer[onceFuture] 91 } 92 93 func (fs *onceFutures) init() { 94 fs.head = new(onceFuture) 95 fs.tail.Store(fs.head) 96 } 97 98 func (fs *onceFutures) append(f future.Future[error]) *onceFuture { 99 of := &onceFuture{Future: f} 100 for { 101 tail := fs.tail.Load() 102 if tail.next.CompareAndSwap(nil, of) { 103 fs.tail.Store(of) 104 return of 105 } 106 } 107 } 108 109 func (fs *onceFutures) Complete(err error) { 110 for of := fs.head.next.Load(); of != nil; of = of.next.Load() { 111 of.Complete(err) 112 } 113 } 114 115 type Lifecycle interface { 116 // Run 在当前协程运行生命周期的整体流程,包括启动的过程和运行的过程。当启动失败或运行退出包含 117 // 错误信息时,此函数返回此错误。 118 Run() error 119 120 // Start 在当前协程执行生命周期的启动流程,当启动成功后会在新的协程运行此生命周期。当启动失败 121 // 时返回错误。 122 Start() error 123 124 // Background 在确定可以启动此生命周期后,使用新的协程运行生命周期的整体流程。返回错误则说明 125 // 不能启动。 126 Background() error 127 128 // Close 通知生命周期进行关闭流程,执行此流程返回成功后,生命周期将在清理资源后关闭。 129 Close() error 130 131 // Shutdown 关闭生命周期,如果返回错误,则说明通知生命周期进行关闭失败。否则将等待生命周期完 132 // 全关闭 133 Shutdown() error 134 135 // State 返回生命周期的当前状态,详见 State 类型。 136 State() State 137 138 // Future 向生命周期中添加指定类型(详见 FutureType)的 future,用于跟踪生命周期状态的变 139 // 化。若生命周期状态已切换到触发状态及以后,则会在此函数中完成指定的 future。 140 Future(FutureType, Future) Future 141 142 // Waiter 获取生命周期状态变化的通知通道。 143 Waiter(FutureType) <-chan error 144 145 //Wait(typ FutureType, interrupter chan struct{}) error 146 147 Before(BeforeCallbackType, BeforeCallback) 148 149 After(AfterCallbackType, AfterCallback) 150 151 OnPanic(PanicCallbackType, PanicCallback) 152 } 153 154 type DefaultLifecycle struct { 155 runner Runner 156 futures [futureTypes]onceFutures 157 beforeCallbacks [beforeCallbackTypes]atomicList[BeforeCallback] 158 afterCallbacks [afterCallbackTypes]atomicList[AfterCallback] 159 panicCallback [panicCallbackTypes]PanicCallback 160 state atomic.Uint32 161 startErr error 162 exitErr error 163 } 164 165 func New(runner Runner) *DefaultLifecycle { 166 if runner == nil { 167 runner = NopRunner() 168 } 169 l := &DefaultLifecycle{runner: runner} 170 for i := range l.futures { 171 l.futures[i].init() 172 } 173 for i := range l.beforeCallbacks { 174 l.beforeCallbacks[i].init() 175 } 176 for i := range l.afterCallbacks { 177 l.afterCallbacks[i].init() 178 } 179 return l 180 } 181 182 func NewWithFunc(startFn StartFunc, runFn RunFunc, closeFn CloseFunc) *DefaultLifecycle { 183 return New(FuncRunner(startFn, runFn, closeFn)) 184 } 185 186 func NewInterrupted(runner InterruptedRunner) *DefaultLifecycle { 187 return New(WrapInterruptedRunner(runner)) 188 } 189 190 func NewInterruptedWithFunc(startFn InterruptedStartFunc, runFn InterruptedRunFunc) *DefaultLifecycle { 191 return New(WrapInterruptedRunner(FuncInterruptedRunner(startFn, runFn))) 192 } 193 194 func NewInterruptedWithStarter(starter InterruptedStarter) *DefaultLifecycle { 195 return New(InterruptedStarterRunner(starter)) 196 } 197 198 func NewInterruptedWithStarterFunc(starterFn InterruptedStarterFunc) *DefaultLifecycle { 199 return New(InterruptedStarterRunner(FuncInterruptedStarter(starterFn))) 200 } 201 202 func (l *DefaultLifecycle) addFuture(typ FutureType, f Future) (*onceFuture, State) { 203 return l.futures[typ].append(f), State(l.state.Load()) 204 } 205 206 func (l *DefaultLifecycle) completeFutures(typ FutureType, err error) { 207 l.futures[typ].Complete(err) 208 } 209 210 func (l *DefaultLifecycle) addBeforeCallback(typ BeforeCallbackType, callback BeforeCallback) { 211 l.beforeCallbacks[typ].append(callback) 212 } 213 214 func (l *DefaultLifecycle) executeBeforeCallbacks(typ BeforeCallbackType) error { 215 for e := l.beforeCallbacks[typ].head.next.Load(); e != nil; e = e.next.Load() { 216 if err := e.value(l); err != nil { 217 return err 218 } 219 } 220 return nil 221 } 222 223 func (l *DefaultLifecycle) addAfterCallback(typ AfterCallbackType, callback AfterCallback) { 224 l.afterCallbacks[typ].append(callback) 225 } 226 227 func (l *DefaultLifecycle) executeAfterCallbacks(typ AfterCallbackType, err error) { 228 for e := l.afterCallbacks[typ].head.next.Load(); e != nil; e = e.next.Load() { 229 e.value(l, err) 230 } 231 } 232 233 func (l *DefaultLifecycle) loadPanicCallback(typ PanicCallbackType) PanicCallback { 234 up := atomic.LoadUintptr((*uintptr)(unsafe.Pointer(&l.panicCallback[typ]))) 235 return *(*PanicCallback)(unsafe.Pointer(&up)) 236 } 237 238 func (l *DefaultLifecycle) storePanicCallback(typ PanicCallbackType, callback PanicCallback) { 239 up := *(*uintptr)(unsafe.Pointer(&callback)) 240 atomic.StoreUintptr((*uintptr)(unsafe.Pointer(&l.panicCallback[typ])), up) 241 } 242 243 func (l *DefaultLifecycle) handlePanic(typ PanicCallbackType, ep *error) { 244 if callback := l.loadPanicCallback(typ); callback != nil { 245 if e := recover(); e != nil { 246 *ep = callback(l, e) 247 } 248 } 249 return 250 } 251 252 func (l *DefaultLifecycle) doStart() (err error) { 253 defer l.handlePanic(PanicOnStarting, &err) 254 return l.runner.DoStart(l) 255 } 256 257 func (l *DefaultLifecycle) start() error { 258 if l.startErr = l.executeBeforeCallbacks(BeforeStart); l.startErr != nil { 259 return l.startErr 260 } 261 l.startErr = l.doStart() 262 l.executeAfterCallbacks(AfterStart, l.startErr) 263 if l.startErr != nil { 264 l.exitErr = l.startErr 265 l.state.Store(uint32(StateClosed)) 266 l.completeFutures(FutureTypeStarted, l.startErr) 267 l.completeFutures(FutureTypeClosed, l.exitErr) 268 } else { 269 l.state.Store(uint32(StateRunning)) 270 l.completeFutures(FutureTypeStarted, nil) 271 } 272 return l.startErr 273 } 274 275 func (l *DefaultLifecycle) doRun() (err error) { 276 defer l.handlePanic(PanicOnRunning, &err) 277 return l.runner.DoRun(l) 278 } 279 280 func (l *DefaultLifecycle) run() error { 281 l.exitErr = l.runner.DoRun(l) 282 l.executeAfterCallbacks(AfterRun, l.exitErr) 283 l.state.Store(uint32(StateClosed)) 284 l.completeFutures(FutureTypeClosed, nil) 285 return l.exitErr 286 } 287 288 func (l *DefaultLifecycle) Runner() Runner { 289 return l.runner 290 } 291 292 func (l *DefaultLifecycle) Run() error { 293 if !l.state.CompareAndSwap(uint32(StateReady), uint32(StateStarting)) { 294 return l.waitClosed() 295 } 296 if err := l.start(); err != nil { 297 return err 298 } 299 return l.run() 300 } 301 302 func (l *DefaultLifecycle) Start() error { 303 if !l.state.CompareAndSwap(uint32(StateReady), uint32(StateStarting)) { 304 return l.waitStarted() 305 } 306 if err := l.start(); err != nil { 307 return err 308 } 309 go l.run() 310 return nil 311 } 312 313 func (l *DefaultLifecycle) Background() error { 314 if !l.state.CompareAndSwap(uint32(StateReady), uint32(StateStarting)) { 315 return nil 316 } 317 go func() { 318 if err := l.start(); err == nil { 319 l.run() 320 } 321 }() 322 return nil 323 } 324 325 func (l *DefaultLifecycle) Close() error { 326 if l.state.CompareAndSwap(uint32(StateReady), uint32(StateClosed)) { 327 // 状态为 Ready 则直接转变状态为 Closed,并触发 future 328 l.completeFutures(FutureTypeStarted, nil) 329 l.completeFutures(FutureTypeClosed, nil) 330 return nil 331 } 332 if state := State(l.state.Load()); state < StateClosed { 333 // 状态为 Starting 或 Running,执行 runner 的 DoClose 方法通知生命周期进行关闭 334 if err := l.executeBeforeCallbacks(BeforeClose); err != nil { 335 return err 336 } 337 err := l.runner.DoClose(l) 338 l.executeAfterCallbacks(AfterClose, err) 339 return err 340 } 341 return nil 342 } 343 344 func (l *DefaultLifecycle) Shutdown() error { 345 if err := l.Close(); err != nil { 346 return err 347 } 348 l.waitClosed() 349 return nil 350 } 351 352 func (l *DefaultLifecycle) State() State { 353 return State(l.state.Load()) 354 } 355 356 func (l *DefaultLifecycle) waitStarted() error { 357 state := l.State() 358 if state > StateStarting { 359 return l.startErr 360 } 361 f := make(future.ChanFuture[error], 1) 362 if _, ns := l.addFuture(FutureTypeStarted, f); ns > StateStarting { 363 return l.startErr 364 } else { 365 return <-f 366 } 367 } 368 369 func (l *DefaultLifecycle) waitClosed() error { 370 state := l.State() 371 if state > StateRunning { 372 return l.exitErr 373 } 374 f := make(future.ChanFuture[error], 1) 375 if _, ns := l.addFuture(FutureTypeClosed, f); ns > StateRunning { 376 return l.exitErr 377 } else { 378 return <-f 379 } 380 } 381 382 func (l *DefaultLifecycle) StartedFuture(f Future) Future { 383 state := l.State() 384 if state > StateStarting { 385 // 状态已经高于触发 future 的阈值,不添加到生命周期中,并且立即完成此 future 386 f.Complete(l.startErr) 387 } else if of, ns := l.addFuture(FutureTypeStarted, f); ns > StateStarting { 388 // 在添加 future 时状态发生切换,由于不确定运行协程是否完成此 future,此处需要手 389 // 动完成,由 onceFuture 来保证 future 只会被完成一次 390 of.Complete(l.startErr) 391 } else { 392 // 将 future 添加到了生命周期中,并且状态没有切换到高于触发 future 的阈值,由生 393 // 命周期运行协程完成此 future 394 } 395 return f 396 } 397 398 func (l *DefaultLifecycle) ClosedFuture(f Future) Future { 399 state := l.State() 400 if state > StateRunning { 401 // 状态已经高于触发 future 的阈值,不添加到生命周期中,并且立即完成此 future 402 f.Complete(l.exitErr) 403 } else if of, ns := l.addFuture(FutureTypeClosed, f); ns > StateRunning { 404 // 在添加 future 时状态发生切换,由于不确定运行协程是否完成此 future,此处需要手 405 // 动完成,由 onceFuture 来保证 future 只会被完成一次 406 of.Complete(l.exitErr) 407 } else { 408 // 将 future 添加到了生命周期中,并且状态没有切换到高于触发 future 的阈值,由生 409 // 命周期运行协程完成此 future 410 } 411 return f 412 } 413 414 func (l *DefaultLifecycle) Future(typ FutureType, f Future) Future { 415 switch typ { 416 case FutureTypeStarted: 417 return l.StartedFuture(f) 418 case FutureTypeClosed: 419 return l.ClosedFuture(f) 420 } 421 return nil 422 } 423 424 func (l *DefaultLifecycle) Waiter(typ FutureType) <-chan error { 425 if typ < futureTypes { 426 waiter := make(future.ChanFuture[error], 1) 427 l.Future(typ, waiter) 428 return waiter 429 } 430 return nil 431 } 432 433 func (l *DefaultLifecycle) Before(typ BeforeCallbackType, callback BeforeCallback) { 434 if typ < beforeCallbackTypes { 435 l.addBeforeCallback(typ, callback) 436 } 437 } 438 439 func (l *DefaultLifecycle) After(typ AfterCallbackType, callback AfterCallback) { 440 if typ < afterCallbackTypes { 441 l.addAfterCallback(typ, callback) 442 } 443 } 444 445 func (l *DefaultLifecycle) OnPanic(typ PanicCallbackType, callback PanicCallback) { 446 if typ < panicCallbackTypes { 447 l.storePanicCallback(typ, callback) 448 } 449 }