Skip to content

Commit 028bf72

Browse files
committed
feat: "max_concurrent_connections"
1 parent 38a9901 commit 028bf72

3 files changed

Lines changed: 34 additions & 3 deletions

File tree

internal/config/config.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ type SiteConfig struct {
3535
ReadHeaderTimeout int `json:"read_header_timeout"` // in seconds
3636
IdleTimeout int `json:"idle_timeout"` // in seconds
3737
MaxHeaderBytes int `json:"max_header_bytes"` // in bytes
38-
FlushInterval string `json:"proxy_flush_interval"`
39-
BufferSizeKB int `json:"buffer_size_kb"`
40-
EnableLogging *bool `json:"enable_logging,omitempty"` // Default true if nil
38+
FlushInterval string `json:"proxy_flush_interval"`
39+
BufferSizeKB int `json:"buffer_size_kb"`
40+
MaxConcurrentConnections int `json:"max_concurrent_connections"`
41+
EnableLogging *bool `json:"enable_logging,omitempty"` // Default true if nil
4142

4243
PluginConfigs map[string]interface{} `json:"plugin_configs"`
4344
}

internal/server/handler.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ func createHandler(conf config.SiteConfig, log *logger.Logger, identifier string
6060
siteMwManager.Use(middleware.TimeoutMiddleware(timeout))
6161
}
6262

63+
// Add Concurrency Middleware
64+
if conf.MaxConcurrentConnections > 0 {
65+
siteMwManager.Use(middleware.ConcurrencyMiddleware(conf.MaxConcurrentConnections))
66+
}
67+
6368
// Add logging middleware last to ensure it wraps the entire request.
6469
// We default to true if the pointer is nil.
6570
if conf.EnableLogging == nil || *conf.EnableLogging {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package middleware
2+
3+
import (
4+
"net/http"
5+
)
6+
7+
// ConcurrencyMiddleware limits the number of concurrent requests.
8+
func ConcurrencyMiddleware(maxConcurrent int) MiddlewareFunc {
9+
// Semaphore channel to limit concurrent access
10+
sem := make(chan struct{}, maxConcurrent)
11+
12+
return func(next http.Handler) http.Handler {
13+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
14+
select {
15+
case sem <- struct{}{}:
16+
// Acquired token
17+
defer func() { <-sem }() // Release token
18+
next.ServeHTTP(w, r)
19+
default:
20+
// Limit reached
21+
http.Error(w, "Service Unavailable (Max Concurrent Connections Reached)", http.StatusServiceUnavailable)
22+
}
23+
})
24+
}
25+
}

0 commit comments

Comments
 (0)