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 }