summaryrefslogtreecommitdiff
path: root/go/src/lib/statusline/ratelimit.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/src/lib/statusline/ratelimit.go')
-rw-r--r--go/src/lib/statusline/ratelimit.go58
1 files changed, 58 insertions, 0 deletions
diff --git a/go/src/lib/statusline/ratelimit.go b/go/src/lib/statusline/ratelimit.go
new file mode 100644
index 0000000..970f8e5
--- /dev/null
+++ b/go/src/lib/statusline/ratelimit.go
@@ -0,0 +1,58 @@
+package statusline
+
+import (
+ "time"
+)
+
+type rateLimiter struct {
+ lines chan string
+ end1 chan bool
+ end2 chan struct{}
+}
+
+func RateLimit(sl StatusLine, d time.Duration) StatusLine {
+ ret := &rateLimiter{
+ lines: make(chan string),
+ end1: make(chan bool),
+ end2: make(chan struct{}),
+ }
+ go func() {
+ ticker := time.NewTicker(d)
+ var oldLine string
+ var newLine string
+ dirty := false
+ for {
+ select {
+ case <-ticker.C:
+ if dirty && newLine != oldLine {
+ sl.Put(newLine)
+ }
+ dirty = false
+ case line := <-ret.lines:
+ newLine = line
+ dirty = true
+ case keep := <-ret.end1:
+ if keep && dirty && newLine != oldLine {
+ sl.Put(newLine)
+ }
+ sl.End(keep)
+ ticker.Stop()
+ ret.end2 <- struct{}{}
+ close(ret.end2)
+ return
+ }
+ }
+ }()
+ return ret
+}
+
+func (sl *rateLimiter) Put(line string) {
+ sl.lines <- line
+}
+
+func (sl *rateLimiter) End(keep bool) {
+ sl.end1 <- keep
+ close(sl.lines)
+ close(sl.end1)
+ <-sl.end2
+}