-
Notifications
You must be signed in to change notification settings - Fork 2
/
throttle.go
48 lines (44 loc) · 875 Bytes
/
throttle.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
package godemon
import (
"time"
)
func nonBlockingDrain(ch <-chan struct{}) int {
n := 0
for {
select {
case <-ch:
n++
default:
return n
}
}
}
func throttleRestarts(events <-chan struct{}) chan struct{} {
restart := make(chan struct{})
go func() {
defer close(restart)
for {
// Wait for first event since last restart
_, ok := <-events
if !ok {
return
}
// Restart immediately. The send here is non-blocking, so the receiver
// will ignore restart attempts while it is already mid-restart.
select {
case restart <- struct{}{}:
default:
}
// Make sure we go at least 50ms with no events before the next restart
// TODO: Make this configurable, and/or adaptive
for {
<-time.After(50 * time.Millisecond)
n := nonBlockingDrain(events)
if n == 0 {
break
}
}
}
}()
return restart
}