From c07fb20a8acd215d127fedde591e275734c789f8 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Tue, 22 Jul 2025 17:38:47 +0200 Subject: [PATCH] Hallucinate a limited http client --- go.mod | 2 ++ go.sum | 2 ++ main.go | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 go.sum diff --git a/go.mod b/go.mod index 20eac22..ae235d5 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module git.site.quack-lab.dev/dave/cyutils go 1.23.6 + +require golang.org/x/time v0.12.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..457536c --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= diff --git a/main.go b/main.go index 099d7c6..1e61d44 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,11 @@ package cyutils import ( + "net/http" "sync" + "time" + + "golang.org/x/time/rate" ) func WithWorkers[T any](workers int, arr []T, fn func(worker int, item T)) { @@ -40,3 +44,39 @@ func Batched[T any](arr []T, batchSize int, fn func(batch []T)) { fn(batch) } } + +type RateLimitedTransport struct { + base http.RoundTripper // Underlying transport + limiter *rate.Limiter // Rate limiter +} + +// RoundTrip enforces rate limiting before executing the request +func (t *RateLimitedTransport) RoundTrip(req *http.Request) (*http.Response, error) { + ctx := req.Context() + if err := t.limiter.Wait(ctx); err != nil { + return nil, err // Handle context cancellation/timeout + } + return t.base.RoundTrip(req) +} +func LimitedHttp(rps float64, burst int, timeout time.Duration) *http.Client { + baseTransport := &http.Transport{ + MaxIdleConns: 100, + MaxIdleConnsPerHost: 10, + IdleConnTimeout: 10 * time.Second, + } + + // Initialize rate limiter + limiter := rate.NewLimiter(rate.Limit(rps), burst) + + // Wrap transport with rate limiting + transport := &RateLimitedTransport{ + base: baseTransport, + limiter: limiter, + } + + // Return configured client + return &http.Client{ + Transport: transport, + Timeout: timeout, + } +}