go
37 lines · 7 steps
Debouncing a stream of events in Go
A timer batches bursts of events and flushes them only after activity goes quiet for 200ms.
Explained by
highlit
1func (w *Watcher) resetDebounce(d time.Duration) {
2 if !w.timer.Stop() {
3 select {
4 case <-w.timer.C:
5 default:
6 }
7 }
8 w.timer.Reset(d)
9}
10
11func (w *Watcher) run(events <-chan Event) {
12 w.timer = time.NewTimer(time.Hour)
13 if !w.timer.Stop() {
14 <-w.timer.C
15 }
16
17 var pending []Event
18 for {
19 select {
20 case ev, ok := <-events:
21 if !ok {
22 if len(pending) > 0 {
23 w.flush(pending)
24 }
25 return
26 }
27 pending = append(pending, ev)
28 w.resetDebounce(200 * time.Millisecond)
29 case <-w.timer.C:
30 w.flush(pending)
31 pending = pending[:0]
32 case <-w.quit:
33 w.timer.Stop()
34 return
35 }
36 }
37}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Debouncing collects rapid events and acts only after a quiet interval, avoiding redundant work.
- 2Draining a stopped timer's channel prevents stale ticks from firing a spurious flush.
- 3A single select loop cleanly multiplexes input, timeout, and shutdown signals.
Related explainers
go
package streaming import ( "bufio"
Streaming NDJSON logs over HTTP in Go
http-streaming
channels
select
Advanced
10 steps
go
package api import ( "crypto/sha256"
ETag conditional requests in Gin
http-caching
etag
conditional-requests
Intermediate
6 steps
go
package logging import ( "context"
Deduplicating log attributes in Go's slog
decorator-pattern
structured-logging
immutability
Intermediate
8 steps
rust
use std::collections::VecDeque; use std::sync::{Arc, Condvar, Mutex}; use std::time::{Duration, Instant};
Building a counting semaphore in Rust
concurrency
synchronization
condition-variable
Advanced
9 steps
go
package middleware import ( "net/http"
Per-plan export limits in Gin middleware
middleware
rate-limiting
authorization
Intermediate
7 steps
go
package httputil import ( "net"
Safely extracting the real client IP in Go
security
http
ip-spoofing
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/debouncing-a-stream-of-events-in-go-explained-go-0273/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.