<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 11 (filtered medium)">
<style>
<!--
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman";}
a:link, span.MsoHyperlink
{color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:Arial;
color:windowtext;}
@page Section1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;}
div.Section1
{page:Section1;}
-->
</style>
</head>
<body lang=EN-US link=blue vlink=purple>
<div class=Section1>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Here is a proposed patch improving the multithread-httpd-backend.
The issue is before it had a circular queue of worker threads and it was always
allocating the request to the next worker, even if that worker was still busy
handling a previous request e.g. some dumb programmer who we won’t
name (allright fine, it was me) has somehow gotten an infinite loop or
something in the render function.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>The new method keeps a stack of available workers that it
pops off of when a new request comes in. When a worker finishes handling a
request it sends a message back to the control-thread who then pushes the worker
back onto the available-workers stack. There is a second patch as well
that splits the multithreaded backend into a separate file. It seemed
that there was enough code here now to warrant that and httpd.lisp was getting
kind of large, but you don’t need to grab that patch if you want to keep
it all in httpd.lisp.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>By default it creates 4 workers when it starts and has a max
worker count of 32. Right now when it exceeds max workers it re-queues
the connection message to the control thread hoping one of the other workers
finishes off in the meantime. This probably isn’t the best strategy. What
happens if a worker never becomes available? Can we check to see if the client
is still connected before re-queuing or something?<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>An alternative might be to just send an error message to the
client saying that the server is too busy. I have the start of a function in
here that should do that (send-error in httpd.lisp, I looked at some of the
other error functions but those all seemed to be at a higher level, I was
trying to avoid reading the full request and just send an error as the
response), except as far as I can tell it never correctly sends anything to the
client. We would probably want this error message to be handled by a separate
thread anyways since we don’t want to block the control-thread while
sending to the client “We’re to busy”. That would probably
just aggravate the situation.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Some mechanism for timing out requests that go on for to
long would probably be a good idea. Have that be one of the options when
starting up the server maybe. Somewhere yesterday I saw a with-timeout macro
(probably swank) that might be useful for this.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>I’ve tested this with SBCL 0.9.5 on linux with
mod_lisp and it seems to work there, but overall this patch should probably be
considered unstable.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>I would work on this a bit more myself but I will be out of
town this weekend and wanted to get what I have out there for other people to
look at. I’m still fairly new to lisp and this is my first attempt at
hacking multithreaded lisp. My handling of conditions is probably not the best.
Maybe some of the veterans out there can look through it a bit and give it a
bit of loving?<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Nathan Bird<o:p></o:p></span></font></p>
</div>
</body>
</html>