2.14 Limiting Requests
The web-server/dispatchers/limit module provides a wrapper dispatcher that limits how many requests are serviced at once.
| (make limit inner [#:over-limit over-limit]) → dispatcher/c |
| limit : number? |
| inner : dispatcher/c |
| over-limit : (symbols 'block 'kill-new 'kill-old) = 'block |
Returns a dispatcher that defers to inner for work, but will forward a maximum of limit requests concurrently.
If there are no additional spaces inside the limit and a new request is received, the over-limit option determines what is done. The default ('block) causes the new request to block until an old request is finished being handled. If over-limit is 'kill-new, then the new request handler is killed – a form of load-shedding. If over-limit is 'kill-old, then the oldest request handler is killed – prioritizing new connections over old. (This setting is a little dangerous because requests might never finish if there is constant load.)
Consider this example:
| #lang racket |
| (require web-server/web-server |
| web-server/http |
| web-server/http/response |
| (prefix-in limit: web-server/dispatchers/limit) |
| (prefix-in filter: web-server/dispatchers/dispatch-filter) |
| (prefix-in sequencer: web-server/dispatchers/dispatch-sequencer)) |
| (serve #:dispatch |
| (sequencer:make |
| (filter:make |
| #rx"/limited" |
| (limit:make |
| 5 |
| (lambda (conn req) |
| (output-response/method |
| conn |
| (make-response/full |
| 200 #"Okay" |
| (current-seconds) TEXT/HTML-MIME-TYPE |
| empty |
| (list (string->bytes/utf-8 |
| (format "hello world ~a" |
| (sort (build-list 100000 (λ x (random 1000))) |
| <))))) |
| (request-method req))) |
| #:over-limit 'block)) |
| (lambda (conn req) |
| (output-response/method |
| conn |
| (make-response/full 200 #"Okay" |
| (current-seconds) TEXT/HTML-MIME-TYPE |
| empty |
| (list #"<html><body>Unlimited</body></html>")) |
| (request-method req)))) |
| #:port 8080) |
| (do-not-return) |