-
Notifications
You must be signed in to change notification settings - Fork 2
/
occasion.go
131 lines (100 loc) · 2.05 KB
/
occasion.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package synckit
import "time"
type Occasion interface {
Deadline() time.Time
NewTimer() TimerHolder
NewFunc(fn func()) TimerHolder
IsExpired() bool
}
type TimerHolder interface {
Channel() <-chan time.Time
Stop()
}
func Never() TimerHolder {
return (*timerWithChan)(nil)
}
func NewTimer(d time.Duration) TimerHolder {
return &timerWithChan{time.NewTimer(d)}
}
func NewTimerWithFunc(d time.Duration, fn func()) TimerHolder {
return &timerWithFn{time.AfterFunc(d, fn)}
}
type timerWithChan struct {
t *time.Timer
}
func (p *timerWithChan) Channel() <-chan time.Time {
if p == nil || p.t == nil {
return nil
}
return p.t.C
}
func (p *timerWithChan) Stop() {
if p == nil || p.t == nil {
return
}
p.t.Stop()
}
type timerWithFn struct {
t *time.Timer
}
func (p *timerWithFn) Channel() <-chan time.Time {
panic("illegal state")
}
func (p *timerWithFn) Stop() {
p.t.Stop()
}
func NewOccasion(deadline time.Time) Occasion {
return factory{deadline}
}
func NewOccasionAfter(d time.Duration) Occasion {
return factory{time.Now().Add(d)}
}
type factory struct {
d time.Time
}
func (p factory) IsExpired() bool {
return p.d.Before(time.Now())
}
func (p factory) Deadline() time.Time {
return p.d
}
func (p factory) NewTimer() TimerHolder {
return NewTimer(time.Until(p.d))
}
func (p factory) NewFunc(fn func()) TimerHolder {
return NewTimerWithFunc(time.Until(p.d), fn)
}
func NeverOccasion() Occasion {
return factoryNever{}
}
type factoryNever struct{}
func (factoryNever) IsExpired() bool {
return false
}
func (factoryNever) Deadline() time.Time {
return time.Time{}
}
func (factoryNever) NewTimer() TimerHolder {
return Never()
}
func (factoryNever) NewFunc(fn func()) TimerHolder {
return Never()
}
func EverOccasion() Occasion {
return factoryEver{}
}
type factoryEver struct {
}
func (factoryEver) IsExpired() bool {
return true
}
func (factoryEver) Deadline() time.Time {
return time.Time{}
}
func (factoryEver) NewTimer() TimerHolder {
return NewTimer(0)
}
func (factoryEver) NewFunc(fn func()) TimerHolder {
go fn()
return Never()
}