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 }