I have written a small wrapper function which use counting semaphore concept to limit number of connections to a particular handler (as this handler is resource consuming). Below is the code which achieve the same.
func LimitNumClients(f http.HandlerFunc, maxClients int) http.HandlerFunc {
// Counting semaphore using a buffered channel
sema := make(chan struct{}, maxClients)
return func(w http.ResponseWriter, req *http.Request) {
sema <- struct{}{}
defer func() { <-sema }()
f(w, req)
}
}
And then wrapper it up in the handler as below
Route{
"Test",
"GET",
/test,
LimitNumClients(testhandler, 5),
},
Now I want to reply back with 501 error when the client limit is reached for any new connection. How to achieve the same.
In short, the fix for Server Reached MaxRequestWorkers Setting error involves tweaking the Apache parameters to handle a large number of visitors. Today, we so how our Support Engineers help customers in handling such situations. PREVENT YOUR SERVER FROM CRASHING!
This is the limit to the number of concurrent requests to be served by Apache. Any number of connection attempts above the MaxRequestWorkers limit will be queued. Website requests always spike up during busy hours. This, in turn, generate too many Apache processes.
Website requests always spike up during busy hours. This, in turn, generate too many Apache processes. If this MaxRequestWorkers value is set too low, there will be long delays in loading the pages during peak hours. And, if it is set to too high, Apache exceeds the hardware limitations and may lead to a server crash.
This occurs when the number of errors reaches the number specified in MaximumErrorCount. Change the MaximumErrorCount or fix the errors. End Warning DTExec: The package execution returned DTSER_FAILURE (1). Started: 3:53:00 PM Finished: 3:53:17 PM Elapsed: 16.875 seconds. The package execution failed. The step failed.
You may use a non-blocking send operation. If that succeeds, continue as normal, if sending on sema
would block, then send back an error and return from the limiter without calling the handler:
return func(w http.ResponseWriter, req *http.Request) {
select {
case sema <- struct{}{}:
default:
http.Error(w, "rate limit reached", 501)
return
}
defer func() { <-sema }()
f(w, req)
}
Also note that to signal a "rate limit reached" error, the returned status code should be HTTP 429 Too Many Requests
, see RFC 6585.
So instead return this:
http.Error(w, "rate limit reached", http.StatusTooManyRequests)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With