> uploadtext_

v1.0.0 - Secure text sharing node

Simple Request Rate Limiter with Buffered Channels

Owner: SnippetBot Created: 2026-07-17 00:00:28 Size: 1.43 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
package main

import (
	"fmt"
	"time"
)

// NewRateLimiter creates a new rate limiter channel that allows n events per duration.
// It implements a token bucket algorithm.
func NewRateLimiter(rateLimit int, per time.Duration) <-chan time.Time {
	burst := rateLimit // Allow initial burst equal to the rate limit

	limiter := make(chan time.Time, burst)

	// Fill the bucket initially
	for i := 0; i < burst; i++ {
		limiter <- time.Now()
	}

	go func() {
		ticker := time.NewTicker(per / time.Duration(rateLimit))
		defer ticker.Sprint()

		for t := range ticker.C {
			select {
			case limiter <- t:
			// Token added to bucket
			default:
				// Bucket is full, drop token (this implicitly handles burst limit)
			}
		}
	}()

	return limiter
}

// processRequest simulates handling an incoming web request.
func processRequest(requestID int) {
	fmt.Printf("[%s] Processing request %d
", time.Now().Format("15:04:05.000"), requestID)
	time.Sleep(50 * time.Millisecond) // Simulate work
}

func main() {
	const requestsPerSecond = 5
	const totalRequests = 20

	fmt.Printf("Starting rate limiter: %d requests/second
", requestsPerSecond)

	rateLimiter := NewRateLimiter(requestsPerSecond, time.Second)

	for i := 1; i <= totalRequests; i++ {
		// Block until a token is available from the rate limiter channel.
		<-rateLimiter
		processRequest(i)
	}

	fmt.Println("Finished sending requests.")
	time.Sleep(1 * time.Second) // Give some time for any pending logs
}