github.com/anjalikarhana/fabric@v2.1.1+incompatible/orderer/common/server/sched.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package server 8 9 import "time" 10 11 type durationSeries func() time.Duration 12 13 // ticker has a channel that will send the 14 // time with intervals computed by the durationSeries. 15 type ticker struct { 16 stopped bool 17 C <-chan time.Time 18 nextInterval durationSeries 19 stopChan chan struct{} 20 } 21 22 // newTicker returns a channel that sends the time at periods 23 // specified by the given durationSeries. 24 func newTicker(nextInterval durationSeries) *ticker { 25 c := make(chan time.Time) 26 ticker := &ticker{ 27 stopChan: make(chan struct{}), 28 C: c, 29 nextInterval: nextInterval, 30 } 31 32 go func() { 33 defer close(c) 34 ticker.run(c) 35 }() 36 37 return ticker 38 } 39 40 func (t *ticker) run(c chan<- time.Time) { 41 for { 42 if t.stopped { 43 return 44 } 45 select { 46 case <-time.After(t.nextInterval()): 47 t.tick(c) 48 case <-t.stopChan: 49 return 50 } 51 } 52 } 53 54 func (t *ticker) tick(c chan<- time.Time) { 55 select { 56 case c <- time.Now(): 57 case <-t.stopChan: 58 t.stopped = true 59 } 60 } 61 62 func (t *ticker) stop() { 63 close(t.stopChan) 64 } 65 66 func exponentialDurationSeries(initialDuration, maxDuration time.Duration) func() time.Duration { 67 exp := &exponentialDuration{ 68 n: initialDuration, 69 max: maxDuration, 70 } 71 return exp.next 72 } 73 74 type exponentialDuration struct { 75 n time.Duration 76 max time.Duration 77 } 78 79 func (exp *exponentialDuration) next() time.Duration { 80 n := exp.n 81 exp.n *= 2 82 if exp.n > exp.max { 83 exp.n = exp.max 84 } 85 return n 86 }