[plt-scheme] Limiting Concurrent Connections to Web Server
Thanks for the catch Matthew. I've done the asynchronous reply technique.
I've also added an 'over-limit' keyword. It has three options: 'block,
'kill-new, and 'kill-old. From the new documentation:
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 handling. 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.)
Jay
On Fri, Jan 16, 2009 at 9:03 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
> At Fri, 16 Jan 2009 08:33:29 -0700, Jay McCarthy wrote:
>> (if (< i num)
>> (wrap-evt in-ch
>> (lambda (req)
>> (channel-put (in-req-reply-ch req) #t)
>> (loop (add1 i)
>> (list* (in-req-partner req) partners))))
>> never-evt)
>
> A detail that I didn't catch before: if the process that sends the
> request terminates just before the `channel-put', then the lock server
> can get get stuck trying to send a reply to a thread that isn't there
> anymore.
>
> The simplest solution is to send the reply asynchronously:
>
> (wrap-evt in-ch
> (lambda (req)
> (thread (lambda ()
> (channel-put (in-req-reply-ch req) #t)))
> (loop (add1 i)
> (list* (in-req-partner req) partners))))
>
> Another solution is to sync on a combination of the thread and a
> channel-put evt:
>
> (lambda (req)
> (sync
> (handle-evt (channel-put-evt (in-req-reply-ch req) #t)
> (lambda ()
> ;; notification accepted
> (loop (add1 i)
> (list* (in-req-partner req) partners))))
> (handle-evt (in-req-partner req)
> (lambda ()
> ;; other thread died first
> (loop i partners)))))
>
> Since your lock server already cleans up for partners that disappear,
> though, the asynchronous reply is probably better.
>
> If a thread can get suspended, and if you're using the latter solution,
> then you'd want to go even further, and have the reply lifted up to the
> main `sync' (because a suspended thread doesn't receive on a channel
> but also isn't dead). I don't think that case applies in the web
> server, though --- and the asynchronous reply covers that case, too.
>
>
--
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://teammccarthy.org/jay
"The glory of God is Intelligence" - D&C 93