[plt-scheme] Limiting Concurrent Connections to Web Server
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.