Skip to content

Commit d40a037

Browse files
authored
Return non-200 HTTP response code if concurrent API requests cross the specified concurrent-request-limit # (#130)
* With Zero backlog and backlog getting timing out immediately with 1ms, all concurrent requests beyond cfg.middleware.concurrentRequestLimit result in immediate non-200 HTTP response * backlogDuration Object does not require parsing string * make backlogLimit, backlogDuration configurable for concurrent requests * update flag type to time.Duration and docs
1 parent ea0242a commit d40a037

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ Usage of ./observatorium:
8383
The name of the HTTP header containing the tenant ID to forward to the metrics upstreams. (default "THANOS-TENANT")
8484
-metrics.write.endpoint string
8585
The endpoint against which to make write requests for metrics.
86+
-middleware.backlog-duration-concurrent-requests duration
87+
The time duration to buffer up concurrent requests. (default 1ms)
88+
-middleware.backlog-limit-concurrent-requests int
89+
The number of concurrent requests that can buffered.
8690
-middleware.concurrent-request-limit int
8791
The limit that controls the number of concurrently processed requests across all tenants. (default 10000)
8892
-middleware.rate-limiter.grpc-address string

main.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,10 @@ type logsConfig struct {
116116
}
117117

118118
type middlewareConfig struct {
119-
rateLimiterAddress string
120-
concurrentRequestLimit int
119+
rateLimiterAddress string
120+
concurrentRequestLimit int
121+
backLogLimitConcurrentRequests int
122+
backLogDurationConcurrentRequests time.Duration
121123
}
122124

123125
type internalTracingConfig struct {
@@ -369,7 +371,9 @@ func main() {
369371
r.Use(middleware.Recoverer)
370372
r.Use(middleware.StripSlashes)
371373
r.Use(middleware.Timeout(middlewareTimeout)) // best set per handler.
372-
r.Use(middleware.Throttle(cfg.middleware.concurrentRequestLimit))
374+
// With default value of zero backlog concurrent requests crossing a rate-limit result in non-200 HTTP response.
375+
r.Use(middleware.ThrottleBacklog(cfg.middleware.concurrentRequestLimit,
376+
cfg.middleware.backLogLimitConcurrentRequests, cfg.middleware.backLogDurationConcurrentRequests))
373377
r.Use(server.Logger(logger))
374378

375379
ins := signalhttp.NewHandlerInstrumenter(reg, []string{"group", "handler"})
@@ -707,6 +711,11 @@ func parseFlags() (config, error) {
707711
" If not specified, local, non-shared rate limiting will be used.")
708712
flag.IntVar(&cfg.middleware.concurrentRequestLimit, "middleware.concurrent-request-limit", 10_000,
709713
"The limit that controls the number of concurrently processed requests across all tenants.")
714+
flag.IntVar(&cfg.middleware.backLogLimitConcurrentRequests, "middleware.backlog-limit-concurrent-requests", 0,
715+
"The number of concurrent requests that can buffered.")
716+
flag.DurationVar(&cfg.middleware.backLogDurationConcurrentRequests, "middleware.backlog-duration-concurrent-requests", 1*time.Millisecond,
717+
"The time duration to buffer up concurrent requests.")
718+
710719
flag.Parse()
711720

712721
metricsReadEndpoint, err := url.ParseRequestURI(rawMetricsReadEndpoint)

0 commit comments

Comments
 (0)