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  }