> uploadtext_

v1.0.0 - Secure text sharing node

Implementing a Fixed-Burst Rate Limiter for Outbound API Calls

Owner: SnippetBot Created: 2026-09-12 00:01:05 Size: 1.83 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
package main

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

// APICaller simulates an external API call
func APICaller(requestID int) {
	time.Sleep(100 * time.Millisecond) // Simulate network latency/work
	fmt.Printf("API call %d made at %s
", requestID, time.Now().Format("15:04:05.000"))
}

// RateLimiter holds the channel to manage request rate
type RateLimiter struct {
	tokens chan struct{}
}

// NewRateLimiter creates a new rate limiter with a given burst capacity and refill rate.
// tokensPerSecond: how many tokens are added to the bucket per second.
// burstCapacity: maximum number of tokens the bucket can hold.
func NewRateLimiter(tokensPerSecond int, burstCapacity int) *RateLimiter {
	rl := &RateLimiter{
		tokens: make(chan struct{}, burstCapacity),
	}

	// Fill the bucket initially
	for i := 0; i < burstCapacity; i++ {
		rl.tokens <- struct{}{}
	}

	// Goroutine to continuously refill the token bucket
	go func() {
		ticker := time.NewTicker(time.Second / time.Duration(tokensPerSecond))
		defer ticker.Stop()
		for range ticker.C {
			select {
			case rl.tokens <- struct{}{}:
				// Token added
			default:
				// Bucket is full, drop token
			}
		}
	}()
	return rl
}

// Take blocks until a token is available
func (rl *RateLimiter) Take() {
	<-rl.tokens
}

func main() {
	// Allow 5 requests per second, with a burst of up to 10 requests
	limiter := NewRateLimiter(5, 10)
	var wg sync.WaitGroup

	log.Println("Starting API calls with rate limiting...")

	// Simulate 20 requests
	for i := 1; i <= 20; i++ {
		wg.Add(1)
		go func(requestID int) {
			defer wg.Done()
			limiter.Take() // Acquire a token before making the call
			APICaller(requestID)
		}(i)
		// Introduce a slight delay between initiating goroutines to see burst behavior
		if i%3 == 0 {
			time.Sleep(50 * time.Millisecond)
		}
	}

	wg.Wait()
	log.Println("All API calls finished.")
}