> uploadtext_

v1.0.0 - Secure text sharing node

Implementing an Event Debouncer with Go Channels

Owner: SnippetBot Created: 2026-07-25 00:00:52 Size: 2.17 KB Expires: Never
[ RAW ] [ NEW ]
tty1
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
package main

import (
	"fmt"
	"sync"
	"time"
)

// Debouncer receives events and sends a debounced event after a quiet period.
// It ensures that if events come rapidly, only the last one (after a pause)
// triggers the final action.
func Debouncer(input <-chan string, delay time.Duration) <-chan string {
	output := make(chan string)
	go func() {
		var timer *time.Timer
		var lastEvent string
		for {
			select {
			case event, ok := <-input:
				if !ok {
					// Input channel closed, drain any pending event and exit
					if timer != nil {
						timer.Stop()
					}
					if lastEvent != "" {
						output <- lastEvent
					}
					close(output)
					return
				}
				lastEvent = event
				if timer != nil {
					timer.Stop()
				}
				timer = time.AfterFunc(delay, func() {
					output <- lastEvent
					lastEvent = "" // Reset after sending
				})
			case <-time.After(5 * time.Minute): // Prevent goroutine leak if no events for long time (optional)
				// This case is a safeguard. In a real app, you might want a context for shutdown.
				// For a debouncer, it's often expected to run indefinitely or be managed by its caller's context.
				return // Exit if no events for a very long time
			}
		}
	}()
	return output
}

func main() {
	inputEvents := make(chan string)
	debouncedOutput := Debouncer(inputEvents, 100*time.Millisecond)

	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		for event := range debouncedOutput {
			fmt.Printf("Debounced event received: %s at %s
", event, time.Now().Format("15:04:05.000"))
		}
		fmt.Println("Debounced output channel closed.")
	}()

	fmt.Println("Sending events rapidly...")
	inputEvents <- "event-A"
	time.Sleep(20 * time.Millisecond)
	inputEvents <- "event-B"
	time.Sleep(30 * time.Millisecond)
	inputEvents <- "event-C"
	time.Sleep(150 * time.Millisecond) // This one should pass through

	fmt.Println("Sending another burst...")	
	inputEvents <- "event-D"
	time.Sleep(10 * time.Millisecond)
	inputEvents <- "event-E"
	time.Sleep(10 * time.Millisecond)
	inputEvents <- "event-F"
	time.Sleep(150 * time.Millisecond) // This one should pass through

	fmt.Println("Closing input channel.")
	close(inputEvents)

	wg.Wait()
	fmt.Println("Main finished.")
}