github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/catgo/cat-go/cat/scheduler.go (about)

     1  package cat
     2  
     3  type scheduleMixin struct {
     4  	isAlive    bool
     5  	signals    chan int
     6  	exitSignal int
     7  }
     8  
     9  type scheduleMixer interface {
    10  	GetName() string
    11  
    12  	handle(signal int)
    13  
    14  	process()
    15  	afterStart()
    16  	beforeStop()
    17  
    18  	getScheduleMixin() *scheduleMixin
    19  }
    20  
    21  func (p *scheduleMixin) handle(signal int) {
    22  	switch signal {
    23  	case signalShutdown:
    24  		p.isAlive = false
    25  	}
    26  }
    27  
    28  func (p *scheduleMixin) process() {
    29  	return
    30  }
    31  
    32  func (p *scheduleMixin) afterStart() {
    33  	return
    34  }
    35  
    36  func (p *scheduleMixin) beforeStop() {
    37  	return
    38  }
    39  
    40  func (p *scheduleMixin) getScheduleMixin() *scheduleMixin {
    41  	return p
    42  }
    43  
    44  func background(p scheduleMixer) {
    45  	mixin := p.getScheduleMixin()
    46  
    47  	mixin.isAlive = true
    48  	p.afterStart()
    49  
    50  	for mixin.isAlive {
    51  		p.process()
    52  	}
    53  
    54  	p.beforeStop()
    55  
    56  	close(mixin.signals)
    57  	scheduler.signals <- mixin.exitSignal
    58  }
    59  
    60  func makeScheduleMixedIn(exitSignal int) scheduleMixin {
    61  	return scheduleMixin{
    62  		isAlive:    false,
    63  		signals:    make(chan int),
    64  		exitSignal: exitSignal,
    65  	}
    66  }
    67  
    68  type catScheduler struct {
    69  	signals chan int
    70  }
    71  
    72  var scheduler = catScheduler{
    73  	signals: make(chan int),
    74  }
    75  
    76  func (p *catScheduler) shutdownAndWaitGroup(items []scheduleMixer) {
    77  	var expectedSignals = make(map[int]string)
    78  	var count = 0
    79  
    80  	for _, v := range items {
    81  		mixin := v.getScheduleMixin()
    82  		if mixin.isAlive {
    83  			mixin.signals <- signalShutdown
    84  			expectedSignals[mixin.exitSignal] = v.GetName()
    85  			count++
    86  		}
    87  	}
    88  
    89  	if count == 0 {
    90  		return
    91  	}
    92  
    93  	for signal := range p.signals {
    94  		if name, ok := expectedSignals[signal]; ok {
    95  			count--
    96  			logger.Info("%s exited.", name)
    97  		} else {
    98  			logger.Warning("Unpredicted signal received: %d", signal)
    99  		}
   100  		if count == 0 {
   101  			break
   102  		}
   103  	}
   104  }
   105  
   106  func (p *catScheduler) shutdown() {
   107  	group1 := []scheduleMixer{&router, &monitor}
   108  	group2 := []scheduleMixer{aggregator.transaction, aggregator.event, aggregator.metric}
   109  	group3 := []scheduleMixer{&sender}
   110  
   111  	disable()
   112  
   113  	logger.Info("Received shutdown request, scheduling...")
   114  
   115  	p.shutdownAndWaitGroup(group1)
   116  	p.shutdownAndWaitGroup(group2)
   117  	p.shutdownAndWaitGroup(group3)
   118  
   119  	logger.Info("All systems down.")
   120  }