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  }