github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/synckit/occasion.go (about) 1 // Copyright 2020 Insolar Network Ltd. 2 // All rights reserved. 3 // This material is licensed under the Insolar License version 1.0, 4 // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md. 5 6 package synckit 7 8 import "time" 9 10 type Occasion interface { 11 Deadline() time.Time 12 NewTimer() TimerHolder 13 NewFunc(fn func()) TimerHolder 14 IsExpired() bool 15 } 16 17 type TimerHolder interface { 18 Channel() <-chan time.Time 19 Stop() 20 } 21 22 func Never() TimerHolder { 23 return (*timerWithChan)(nil) 24 } 25 26 func NewTimer(d time.Duration) TimerHolder { 27 return &timerWithChan{time.NewTimer(d)} 28 } 29 30 func NewTimerWithFunc(d time.Duration, fn func()) TimerHolder { 31 return &timerWithFn{time.AfterFunc(d, fn)} 32 } 33 34 type timerWithChan struct { 35 t *time.Timer 36 } 37 38 func (p *timerWithChan) Channel() <-chan time.Time { 39 if p == nil || p.t == nil { 40 return nil 41 } 42 return p.t.C 43 } 44 45 func (p *timerWithChan) Stop() { 46 if p == nil || p.t == nil { 47 return 48 } 49 p.t.Stop() 50 } 51 52 type timerWithFn struct { 53 t *time.Timer 54 } 55 56 func (p *timerWithFn) Channel() <-chan time.Time { 57 panic("illegal state") 58 } 59 60 func (p *timerWithFn) Stop() { 61 p.t.Stop() 62 } 63 64 func NewOccasion(deadline time.Time) Occasion { 65 return factory{deadline} 66 } 67 68 func NewOccasionAfter(d time.Duration) Occasion { 69 return factory{time.Now().Add(d)} 70 } 71 72 type factory struct { 73 d time.Time 74 } 75 76 func (p factory) IsExpired() bool { 77 return p.d.Before(time.Now()) 78 } 79 80 func (p factory) Deadline() time.Time { 81 return p.d 82 } 83 84 func (p factory) NewTimer() TimerHolder { 85 return NewTimer(time.Until(p.d)) 86 } 87 88 func (p factory) NewFunc(fn func()) TimerHolder { 89 return NewTimerWithFunc(time.Until(p.d), fn) 90 } 91 92 func NeverOccasion() Occasion { 93 return factoryNever{} 94 } 95 96 type factoryNever struct{} 97 98 func (factoryNever) IsExpired() bool { 99 return false 100 } 101 102 func (factoryNever) Deadline() time.Time { 103 return time.Time{} 104 } 105 106 func (factoryNever) NewTimer() TimerHolder { 107 return Never() 108 } 109 110 func (factoryNever) NewFunc(fn func()) TimerHolder { 111 return Never() 112 } 113 114 func EverOccasion() Occasion { 115 return factoryEver{} 116 } 117 118 type factoryEver struct { 119 } 120 121 func (factoryEver) IsExpired() bool { 122 return true 123 } 124 125 func (factoryEver) Deadline() time.Time { 126 return time.Time{} 127 } 128 129 func (factoryEver) NewTimer() TimerHolder { 130 return NewTimer(0) 131 } 132 133 func (factoryEver) NewFunc(fn func()) TimerHolder { 134 go fn() 135 return Never() 136 }