From evenson at panix.com Sat May 8 08:43:31 2010 From: evenson at panix.com (Mark Evenson) Date: Sat, 08 May 2010 10:43:31 +0200 Subject: [hunchentoot-devel] Patches for ABCL to hunchentoot, trivial-gray-streams, flexi-streams, and chunga Message-ID: <4BE52433.9000608@panix.com> I've [assembled instructions for running Hunchentoot on ABCL][1], which includes minor patches to hunchentoot, trivial-gray-streams, flexi-streams, and chunga. The patches seem to be tested well enough now that I ask that the respective package maintainers consider applying the patches to their distribution. Hopefully, all the package maintainers will see this message, although I'm not quite sure about the status of trivial-gray-streams, so corrections and/or forwarding to the proper maintainers are solicited. If package maintainers have further work or critiques to the proposed patches that I should do, please don't hesitate to ask. [1]: http://slack.net/~evenson/abcl/hunchentoot/ -- "A screaming comes across the sky. It has happened before, but there is nothing to compare to it now." From edi at agharta.de Sat May 8 09:50:37 2010 From: edi at agharta.de (Edi Weitz) Date: Sat, 8 May 2010 11:50:37 +0200 Subject: [hunchentoot-devel] Patches for ABCL to hunchentoot, trivial-gray-streams, flexi-streams, and chunga In-Reply-To: <4BE52433.9000608@panix.com> References: <4BE52433.9000608@panix.com> Message-ID: Hi Mark, Thanks for the patches. They look technically OK to me. However, the flexi-streams and chunga patches seem to be needed only because ABCL deliberately deviates from the Gray streams standard. In these two cases I'd rather - if only for reasons of readability - not "pollute" the main code. I think it'd be better if we added a new ABCL-only file where functions with the correct names are exported. That will also make it easier to get rid of these changes once the ABCL maintainers decide to use the correct names. Once this is done, I'll happily apply the patches. Also, for trivial-gray-streams the patches should be sent to David or rather the respective mailing list. I'm not sure if David reads this list. Thanks, Edi. On Sat, May 8, 2010 at 10:43 AM, Mark Evenson wrote: > I've [assembled instructions for running Hunchentoot on ABCL][1], which > includes minor patches to hunchentoot, trivial-gray-streams, > flexi-streams, and chunga. > > The patches seem to be tested well enough now that I ask that the > respective package maintainers consider applying the patches to their > distribution. ?Hopefully, all the package maintainers will see this > message, although I'm not quite sure about the status of > trivial-gray-streams, so corrections and/or forwarding to the proper > maintainers are solicited. > > If package maintainers have further work or critiques to the proposed > patches that I should do, please don't hesitate to ask. > > [1]: http://slack.net/~evenson/abcl/hunchentoot/ > > -- > "A screaming comes across the sky. ?It has happened before, but there > is nothing to compare to it now." > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > > From JEFFREY.K.CUNNINGHAM at saic.com Mon May 10 21:42:11 2010 From: JEFFREY.K.CUNNINGHAM at saic.com (Cunningham, Jeffrey K.) Date: Mon, 10 May 2010 14:42:11 -0700 Subject: [hunchentoot-devel] hunchentoot page not rendering correctly in two recent browsers Message-ID: <81FD505273524544875A4C14653705BA08FF6BCB@0461-its-exmb02.us.saic.com> Here at work I have available Epiphany 2.28.0 and Firefox 3.5.7 (both Linux). The latter renders the http://weitz.de/hunchentoot page with errors (looks like some of the head section is coming out as HTML before the first h1 tag), and the former refuses to render it at all - producing "This page contains the following errors:..." message. I have attached pngs of each for troubleshooting, though I don't know if they will go through the list server. If not I will post them on another server tonight and post a link. Both browsers are set up with defaults as installed in US. Jeffrey Cunningham Space Systems Development Division Space & Geospatial Intelligence Business Unit Science Applications International Corporation ph: 253.867.3792 fx: 253.867.1504 jeffrey.k.cunningham at saic.com -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image002.jpg Type: image/jpeg Size: 1687 bytes Desc: image002.jpg URL: From JEFFREY.K.CUNNINGHAM at saic.com Mon May 10 21:43:22 2010 From: JEFFREY.K.CUNNINGHAM at saic.com (Cunningham, Jeffrey K.) Date: Mon, 10 May 2010 14:43:22 -0700 Subject: [hunchentoot-devel] hunchentoot page not rendering correctly in two recent browsers Message-ID: <81FD505273524544875A4C14653705BA08FF6BD0@0461-its-exmb02.us.saic.com> Forgot the attachments JKC ________________________________ From: Cunningham, Jeffrey K. Sent: Monday, May 10, 2010 2:42 PM To: 'tbnl-devel at common-lisp.net' Subject: hunchentoot page not rendering correctly in two recent browsers Here at work I have available Epiphany 2.28.0 and Firefox 3.5.7 (both Linux). The latter renders the http://weitz.de/hunchentoot page with errors (looks like some of the head section is coming out as HTML before the first h1 tag), and the former refuses to render it at all - producing "This page contains the following errors:..." message. I have attached pngs of each for troubleshooting, though I don't know if they will go through the list server. If not I will post them on another server tonight and post a link. Both browsers are set up with defaults as installed in US. Jeffrey Cunningham Space Systems Development Division Space & Geospatial Intelligence Business Unit Science Applications International Corporation ph: 253.867.3792 fx: 253.867.1504 jeffrey.k.cunningham at saic.com -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.jpg Type: image/jpeg Size: 1687 bytes Desc: image001.jpg URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: hunchpage.png Type: image/png Size: 123160 bytes Desc: hunchpage.png URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: hunchpage-epiph.png Type: image/png Size: 41767 bytes Desc: hunchpage-epiph.png URL: From edi at agharta.de Mon May 10 22:16:14 2010 From: edi at agharta.de (Edi Weitz) Date: Tue, 11 May 2010 00:16:14 +0200 Subject: [hunchentoot-devel] hunchentoot page not rendering correctly in two recent browsers In-Reply-To: <81FD505273524544875A4C14653705BA08FF6BCB@0461-its-exmb02.us.saic.com> References: <81FD505273524544875A4C14653705BA08FF6BCB@0461-its-exmb02.us.saic.com> Message-ID: The problem with Firefox is new to me and I can't reproduce it. Problems with more esoteric browsers have been discussed before, please search the mailing list archives. Thanks for the report, Edi. On Mon, May 10, 2010 at 11:42 PM, Cunningham, Jeffrey K. wrote: > > Here at work I have available Epiphany 2.28.0 and Firefox 3.5.7 (both Linux). The latter renders the http://weitz.de/hunchentoot page with errors (looks like some of the head section is coming out as HTML before the first h1 tag), and the former refuses to render it at all ? producing ?This page contains the following errors:?? message. I have attached pngs of each for troubleshooting, though I don?t know if they will go through the list server. If not I will post them on another server tonight and post a link. Both browsers are set up with defaults as installed in US. > > > > Jeffrey Cunningham > > Space Systems Development?Division > > Space & Geospatial Intelligence Business Unit > > Science Applications International Corporation > > ph:? 253.867.3792 > > fx:?? 253.867.1504 > > jeffrey.k.cunningham at saic.com > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel From J.k.cunningham at comcast.net Tue May 11 01:05:35 2010 From: J.k.cunningham at comcast.net (J. K. Cunningham) Date: Mon, 10 May 2010 18:05:35 -0700 Subject: [hunchentoot-devel] authorization fail to redirect? In-Reply-To: <1273504817.14379.24.camel@golum.olympus.net> References: <1273504817.14379.24.camel@golum.olympus.net> Message-ID: <1273539935.14379.26.camel@golum.olympus.net> Hi, Is there a relatively simple way to make REQUIRE-AUTHORIZATION fail to the REDIRECT function so the user doesn't see the error return response? I've tried a number of things without success so far. I would like to have it work so that the user can back out gracefully if he hits "Cancel" rather than attempt a username-password. Redirecting to the page of origin would be perfect. Thanks. Jeff Cunningham -------------- next part -------------- An HTML attachment was scrubbed... URL: From zaries at global.co.za Sat May 15 11:32:24 2010 From: zaries at global.co.za (Phil Marneweck) Date: Sat, 15 May 2010 13:32:24 +0200 Subject: [hunchentoot-devel] static-file-dispatcher-and-handler for specific acceptor Message-ID: <1273923144.1913.34.camel@scatha> Hi How do I make create-static-file-dispatcher-and-handler to be relevant for a specific acceptor only? Usually I would just push it onto the *dispatch-table*, but that is global. Or am I missing something obvious again? Thanx From gordon at itasoftware.com Sat May 15 12:53:12 2010 From: gordon at itasoftware.com (Gordon Sims) Date: Sat, 15 May 2010 08:53:12 -0400 Subject: [hunchentoot-devel] Oh! Let me float in your pool! Message-ID: <4BEE9938.4060508@itasoftware.com> DRAKMA: [singing] ...Yes, YOU'RE ALL REAL COOL, with those little WEBS you SPOOL and all your 'SPIDER DROOL'... Oh! Let me float in your pool! HUNCHENTOOT: [disgruntled] "What you want NOW, bitch?" -- GORDON: [ambitiously hacking] I'd like to have two settings in Hunchentoot to control the maximum number of worker threads, and how many connections are accepted (and queued) for processing when the maximum is exceeded. If the maximum is exceeded, new connection attempts should be refused. This is analogous to Tomcat's maxThreads and acceptCount settings. It could be implemented by a pool of worker threads. Is this a concept that anybody has experimented yet with current version of Hunchentoot? Are there any thoughts about how a thread pool should work, especially the coordination (or division of responsibility) between ACCEPTOR and TASKMASTER objects? Any portability concerns? thanks, -Gordon From amalawi at gmail.com Sat May 15 15:34:50 2010 From: amalawi at gmail.com (Ala'a (cmo-0)) Date: Sat, 15 May 2010 19:34:50 +0400 Subject: [hunchentoot-devel] static-file-dispatcher-and-handler for specific acceptor In-Reply-To: <1273923144.1913.34.camel@scatha> References: <1273923144.1913.34.camel@scatha> Message-ID: Check request-dispatcher slot of the acceptor class in hunchentoot. On Sat, May 15, 2010 at 3:32 PM, Phil Marneweck wrote: > Hi > > How do I make create-static-file-dispatcher-and-handler to be relevant > for a specific acceptor only? > > Usually I would just push it onto the *dispatch-table*, but that is > global. > > Or am I missing something obvious again? > > Thanx > > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > From hans.huebner at gmail.com Sat May 15 20:39:56 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Sat, 15 May 2010 22:39:56 +0200 Subject: [hunchentoot-devel] Oh! Let me float in your pool! In-Reply-To: <4BEE9938.4060508@itasoftware.com> References: <4BEE9938.4060508@itasoftware.com> Message-ID: Hi Gordon, On Sat, May 15, 2010 at 14:53, Gordon Sims wrote: > GORDON: [ambitiously hacking] I'd like to have two settings in > Hunchentoot to control the maximum number of worker threads, and how > many connections are accepted (and queued) for processing when the > maximum is exceeded. ?If the maximum is exceeded, new connection > attempts should be refused. ?This is analogous to Tomcat's maxThreads > and acceptCount settings. ?It could be implemented by a pool of worker > threads. ?Is this a concept that anybody has experimented yet with > current version of Hunchentoot? Are there any thoughts about how a > thread pool should work, especially the coordination (or division of > responsibility) between ACCEPTOR and TASKMASTER objects? ?Any > portability concerns? I can't really give you good advice, but the ACCEPTOR and TASKMASTER classes have been invented to support thread pooling in addition to the single threaded TASKMASTER subclass. It would be great to have a thread pooling implementation in the base code, presumably based on BORDEAUX-THREADS. Let's see some code :) -Hans From zaries at global.co.za Wed May 19 10:46:09 2010 From: zaries at global.co.za (Phil Marneweck) Date: Wed, 19 May 2010 12:46:09 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! Message-ID: <1274265969.31570.13.camel@scatha> Hi Is there any thing more than *session-gc-frequency* and *session-max-time* that influences session time outs? Because it does not matter how high I set these values the session keeps on timing out with in a couple of minutes! Can those values be set at any time or do they have to be set before any acceptors are created? Any help would be much appreciated this is causing me major pain on a live site. From hans.huebner at gmail.com Wed May 19 11:13:13 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Wed, 19 May 2010 13:13:13 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274265969.31570.13.camel@scatha> References: <1274265969.31570.13.camel@scatha> Message-ID: Phil, are you sure that youre new value for *SESSION-MAX-TIME* is used by your sessions? Try tracing HUNCHENTOOT::SESSION-TOO-OLD-P and check the log file for entries saying "Session with ID too old". If you see those messages in the log, or if HUNCHENTOOT::SESSION-TOO-OLD-P returns a true value for a session, your *SESSION-MAX-TIME* change has not been seen by Hunchentoot. One reason could be that you're changing the value of the global variable after you started Hunchentoot in multi-threaded mode. In that case, the changed value might not be picked up. Let us know how you proceed. -Hans On Wed, May 19, 2010 at 12:46, Phil Marneweck wrote: > Hi > > Is there any thing more than *session-gc-frequency* and > *session-max-time* that influences session time outs? > > Because it does not matter how high I set these values the session keeps > on timing out with in a couple of minutes! > > Can those values be set at any time or do they have to be set before any > acceptors are created? > > Any help would be much appreciated this is causing me major pain on a > live site. > > > > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > From edi at agharta.de Wed May 19 11:41:46 2010 From: edi at agharta.de (Edi Weitz) Date: Wed, 19 May 2010 13:41:46 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: References: <1274265969.31570.13.camel@scatha> Message-ID: In addition to what Hans said, note that there's a per-session slot which you can read and set: http://weitz.de/hunchentoot/#session-max-time Edi. On Wed, May 19, 2010 at 1:13 PM, Hans H?bner wrote: > Phil, > > are you sure that youre new value for *SESSION-MAX-TIME* is used by > your sessions? ?Try tracing HUNCHENTOOT::SESSION-TOO-OLD-P and check > the log file for entries saying "Session with ID too old". ?If > you see those messages in the log, or if > HUNCHENTOOT::SESSION-TOO-OLD-P returns a true value for a session, > your *SESSION-MAX-TIME* change has not been seen by Hunchentoot. > > One reason could be that you're changing the value of the global > variable after you started Hunchentoot in multi-threaded mode. ?In > that case, the changed value might not be picked up. > > Let us know how you proceed. > > -Hans > > On Wed, May 19, 2010 at 12:46, Phil Marneweck wrote: >> Hi >> >> Is there any thing more than *session-gc-frequency* and >> *session-max-time* that influences session time outs? >> >> Because it does not matter how high I set these values the session keeps >> on timing out with in a couple of minutes! >> >> Can those values be set at any time or do they have to be set before any >> acceptors are created? >> >> Any help would be much appreciated this is causing me major pain on a >> live site. >> >> >> >> >> >> >> _______________________________________________ >> tbnl-devel site list >> tbnl-devel at common-lisp.net >> http://common-lisp.net/mailman/listinfo/tbnl-devel >> > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > > From zaries at global.co.za Wed May 19 13:13:43 2010 From: zaries at global.co.za (Phil Marneweck) Date: Wed, 19 May 2010 15:13:43 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: References: <1274265969.31570.13.camel@scatha> Message-ID: <1274274823.1658.78.camel@scatha> Thanx for the speedy feedback. I had to wait to for an opportune moment to shut down hunchentoot on my live server. Steps 1. I restarted it with the *session-gc-frequency* (5000) and *session-max-time* (3600) values I wanted (before I creating any acceptors). 2. Logged into my application and then left the system for 15 minutes, it timed out when I tried to resume. 3. I then placed a trace on HUNCHENTOOT::SESSION-TOO-OLD-P as suggested and it comes back with a NIL, I pushed the system to make more than 50 new sessions. 4. I logged in again and left the system for 15 minutes and again it timed out when I tried to resume. All this time HUNCHENTOOT::SESSION-TOO-OLD-P is returning NIL. I know I am grasping at straws now, but could the *SESSION-MAX-TIME* not working have something to do with the fact that the client and the server are in different time zones? If I run the server on my development box the session does not time out like on the server. Regards Phil On Wed, 2010-05-19 at 13:13 +0200, Hans H?bner wrote: > Phil, > > are you sure that youre new value for *SESSION-MAX-TIME* is used by > your sessions? Try tracing HUNCHENTOOT::SESSION-TOO-OLD-P and check > the log file for entries saying "Session with ID too old". If > you see those messages in the log, or if > HUNCHENTOOT::SESSION-TOO-OLD-P returns a true value for a session, > your *SESSION-MAX-TIME* change has not been seen by Hunchentoot. > > One reason could be that you're changing the value of the global > variable after you started Hunchentoot in multi-threaded mode. In > that case, the changed value might not be picked up. > > Let us know how you proceed. > > -Hans > > On Wed, May 19, 2010 at 12:46, Phil Marneweck wrote: > > Hi > > > > Is there any thing more than *session-gc-frequency* and > > *session-max-time* that influences session time outs? > > > > Because it does not matter how high I set these values the session keeps > > on timing out with in a couple of minutes! > > > > Can those values be set at any time or do they have to be set before any > > acceptors are created? > > > > Any help would be much appreciated this is causing me major pain on a > > live site. > > > > > > > > > > > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From edi at agharta.de Wed May 19 14:10:57 2010 From: edi at agharta.de (Edi Weitz) Date: Wed, 19 May 2010 16:10:57 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274274823.1658.78.camel@scatha> References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> Message-ID: If it times out after 15 minutes, I'd guess this has nothing to do with session timeouts (as witnessed by session-too-old-p returning NIL) because the default timeout is 30 minutes. Are you sure there's not a problem with cookies somewhere? On Wed, May 19, 2010 at 3:13 PM, Phil Marneweck wrote: > Thanx for the speedy feedback. > > I had to wait to for an opportune moment to shut down hunchentoot on my live > server. > > Steps > > 1. I restarted it with the *session-gc-frequency* (5000) and > *session-max-time* (3600) values I wanted (before I creating any acceptors). > > 2. Logged into my application and then left the system for 15 minutes, it > timed out when I tried to resume. > > 3. I then placed a trace on HUNCHENTOOT::SESSION-TOO-OLD-P as suggested and > it comes back with a NIL, I pushed the system to make more than 50 new > sessions. > > 4. I logged in again and left the system for 15 minutes and again it timed > out when I tried to resume. All this time HUNCHENTOOT::SESSION-TOO-OLD-P is > returning NIL. > > I know I am grasping at straws now, but could the *SESSION-MAX-TIME* not > working have something to do with the fact that the client and the server > are in different time zones? If I run the server on my development box the > session does not time out like on the server. > > > Regards > Phil > > > On Wed, 2010-05-19 at 13:13 +0200, Hans H?bner wrote: > > Phil, > > are you sure that youre new value for *SESSION-MAX-TIME* is used by > your sessions? Try tracing HUNCHENTOOT::SESSION-TOO-OLD-P and check > the log file for entries saying "Session with ID too old". If > you see those messages in the log, or if > HUNCHENTOOT::SESSION-TOO-OLD-P returns a true value for a session, > your *SESSION-MAX-TIME* change has not been seen by Hunchentoot. > > One reason could be that you're changing the value of the global > variable after you started Hunchentoot in multi-threaded mode. In > that case, the changed value might not be picked up. > > Let us know how you proceed. > > -Hans > > On Wed, May 19, 2010 at 12:46, Phil Marneweck wrote: >> Hi >> >> Is there any thing more than *session-gc-frequency* and >> *session-max-time* that influences session time outs? >> >> Because it does not matter how high I set these values the session keeps >> on timing out with in a couple of minutes! >> >> Can those values be set at any time or do they have to be set before any >> acceptors are created? >> >> Any help would be much appreciated this is causing me major pain on a >> live site. >> >> >> >> >> >> >> _______________________________________________ >> tbnl-devel site list >> tbnl-devel at common-lisp.net >> http://common-lisp.net/mailman/listinfo/tbnl-devel >> > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > From hans.huebner at gmail.com Wed May 19 13:57:54 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Wed, 19 May 2010 15:57:54 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274274823.1658.78.camel@scatha> References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> Message-ID: Phil, I don't have an explanation for the behavior that you describe. If I had the problem, I'd look at HTTP header traces (to see if the session cookie has an unexpected expiration), trace some more functions (those that call SESSION-TOO-OLD-P in particular) and the like. The problem could also be related to some header rewriting HTTP proxy in between, but all that is only speculation. I'd also make an experiment with an out-of-the-box Hunchentoot and the hunchentoot-test package: I'd play around with various *SESSION-MAX-TIME* settings to see whether the behavior is as expected in an isolated setting. From there, I'd try to find out how the production environment differs. It is certainly possible that Hunchentoot does not work, but I'm kind of reluctant to assume that given the little evidence and analysis that is available in your case. -Hans On Wed, May 19, 2010 at 15:13, Phil Marneweck wrote: > Thanx for the speedy feedback. > > I had to wait to for an opportune moment to shut down hunchentoot on my live > server. > > Steps > > 1. I restarted it with the *session-gc-frequency* (5000) and > *session-max-time* (3600) values I wanted (before I creating any acceptors). > > 2. Logged into my application and then left the system for 15 minutes, it > timed out when I tried to resume. > > 3. I then placed a trace on HUNCHENTOOT::SESSION-TOO-OLD-P as suggested and > it comes back with a NIL, I pushed the system to make more than 50 new > sessions. > > 4. I logged in again and left the system for 15 minutes and again it timed > out when I tried to resume. All this time HUNCHENTOOT::SESSION-TOO-OLD-P is > returning NIL. > > I know I am grasping at straws now, but could the *SESSION-MAX-TIME* not > working have something to do with the fact that the client and the server > are in different time zones? If I run the server on my development box the > session does not time out like on the server. > > > Regards > Phil > > > On Wed, 2010-05-19 at 13:13 +0200, Hans H?bner wrote: > > Phil, > > are you sure that youre new value for *SESSION-MAX-TIME* is used by > your sessions? Try tracing HUNCHENTOOT::SESSION-TOO-OLD-P and check > the log file for entries saying "Session with ID too old". If > you see those messages in the log, or if > HUNCHENTOOT::SESSION-TOO-OLD-P returns a true value for a session, > your *SESSION-MAX-TIME* change has not been seen by Hunchentoot. > > One reason could be that you're changing the value of the global > variable after you started Hunchentoot in multi-threaded mode. In > that case, the changed value might not be picked up. > > Let us know how you proceed. > > -Hans > > On Wed, May 19, 2010 at 12:46, Phil Marneweck wrote: >> Hi >> >> Is there any thing more than *session-gc-frequency* and >> *session-max-time* that influences session time outs? >> >> Because it does not matter how high I set these values the session keeps >> on timing out with in a couple of minutes! >> >> Can those values be set at any time or do they have to be set before any >> acceptors are created? >> >> Any help would be much appreciated this is causing me major pain on a >> live site. >> >> >> >> >> >> >> _______________________________________________ >> tbnl-devel site list >> tbnl-devel at common-lisp.net >> http://common-lisp.net/mailman/listinfo/tbnl-devel >> > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > From zaries at global.co.za Wed May 19 14:41:55 2010 From: zaries at global.co.za (Phil Marneweck) Date: Wed, 19 May 2010 16:41:55 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> Message-ID: <1274280115.1658.134.camel@scatha> I think the culpret might have been *use-remote-addr-for-sessions* I found some forgotten code that sets it to t. Appologies if this was a wild goose chase... I have removed it now and will monitor the situation. Thanx for the help your question about cookies triggered the search for *use-remote-addr-for-sessions*. Once again sorry if this was a wild goose chase, I feel like a real idiot now....*sigh* On Wed, 2010-05-19 at 16:10 +0200, Edi Weitz wrote: > If it times out after 15 minutes, I'd guess this has nothing to do > with session timeouts (as witnessed by session-too-old-p returning > NIL) because the default timeout is 30 minutes. Are you sure there's > not a problem with cookies somewhere? > > > On Wed, May 19, 2010 at 3:13 PM, Phil Marneweck wrote: > > Thanx for the speedy feedback. > > > > I had to wait to for an opportune moment to shut down hunchentoot on my live > > server. > > > > Steps > > > > 1. I restarted it with the *session-gc-frequency* (5000) and > > *session-max-time* (3600) values I wanted (before I creating any acceptors). > > > > 2. Logged into my application and then left the system for 15 minutes, it > > timed out when I tried to resume. > > > > 3. I then placed a trace on HUNCHENTOOT::SESSION-TOO-OLD-P as suggested and > > it comes back with a NIL, I pushed the system to make more than 50 new > > sessions. > > > > 4. I logged in again and left the system for 15 minutes and again it timed > > out when I tried to resume. All this time HUNCHENTOOT::SESSION-TOO-OLD-P is > > returning NIL. > > > > I know I am grasping at straws now, but could the *SESSION-MAX-TIME* not > > working have something to do with the fact that the client and the server > > are in different time zones? If I run the server on my development box the > > session does not time out like on the server. > > > > > > Regards > > Phil > > > > > > On Wed, 2010-05-19 at 13:13 +0200, Hans H?bner wrote: > > > > Phil, > > > > are you sure that youre new value for *SESSION-MAX-TIME* is used by > > your sessions? Try tracing HUNCHENTOOT::SESSION-TOO-OLD-P and check > > the log file for entries saying "Session with ID too old". If > > you see those messages in the log, or if > > HUNCHENTOOT::SESSION-TOO-OLD-P returns a true value for a session, > > your *SESSION-MAX-TIME* change has not been seen by Hunchentoot. > > > > One reason could be that you're changing the value of the global > > variable after you started Hunchentoot in multi-threaded mode. In > > that case, the changed value might not be picked up. > > > > Let us know how you proceed. > > > > -Hans > > > > On Wed, May 19, 2010 at 12:46, Phil Marneweck wrote: > >> Hi > >> > >> Is there any thing more than *session-gc-frequency* and > >> *session-max-time* that influences session time outs? > >> > >> Because it does not matter how high I set these values the session keeps > >> on timing out with in a couple of minutes! > >> > >> Can those values be set at any time or do they have to be set before any > >> acceptors are created? > >> > >> Any help would be much appreciated this is causing me major pain on a > >> live site. > >> > >> > >> > >> > >> > >> > >> _______________________________________________ > >> tbnl-devel site list > >> tbnl-devel at common-lisp.net > >> http://common-lisp.net/mailman/listinfo/tbnl-devel > >> > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel From zaries at global.co.za Thu May 20 04:41:23 2010 From: zaries at global.co.za (Phil Marneweck) Date: Thu, 20 May 2010 06:41:23 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274280115.1658.134.camel@scatha> References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> <1274280115.1658.134.camel@scatha> Message-ID: <1274330483.1658.168.camel@scatha> Just some feedback: *use-remote-addr-for-sessions* was definately the problem, or shall I say my understanding of proxy servers was the problem...well you live and you learn... Thanx again for the help. PS: How about some cross references in the documentation for *session-gc-frequency*, *session-max-time* and *use-remote-addr-for-sessions* just as a heads up for other people that might stumble into this? On Wed, 2010-05-19 at 16:41 +0200, Phil Marneweck wrote: > I think the culpret might have been *use-remote-addr-for-sessions* I > found some forgotten code that sets it to t. Appologies if this was a > wild goose chase... > > I have removed it now and will monitor the situation. > > Thanx for the help your question about cookies triggered the search for > *use-remote-addr-for-sessions*. > > Once again sorry if this was a wild goose chase, I feel like a real > idiot now....*sigh* > > On Wed, 2010-05-19 at 16:10 +0200, Edi Weitz wrote: > > If it times out after 15 minutes, I'd guess this has nothing to do > > with session timeouts (as witnessed by session-too-old-p returning > > NIL) because the default timeout is 30 minutes. Are you sure there's > > not a problem with cookies somewhere? > > > > > > On Wed, May 19, 2010 at 3:13 PM, Phil Marneweck wrote: > > > Thanx for the speedy feedback. > > > > > > I had to wait to for an opportune moment to shut down hunchentoot on my live > > > server. > > > > > > Steps > > > > > > 1. I restarted it with the *session-gc-frequency* (5000) and > > > *session-max-time* (3600) values I wanted (before I creating any acceptors). > > > > > > 2. Logged into my application and then left the system for 15 minutes, it > > > timed out when I tried to resume. > > > > > > 3. I then placed a trace on HUNCHENTOOT::SESSION-TOO-OLD-P as suggested and > > > it comes back with a NIL, I pushed the system to make more than 50 new > > > sessions. > > > > > > 4. I logged in again and left the system for 15 minutes and again it timed > > > out when I tried to resume. All this time HUNCHENTOOT::SESSION-TOO-OLD-P is > > > returning NIL. > > > > > > I know I am grasping at straws now, but could the *SESSION-MAX-TIME* not > > > working have something to do with the fact that the client and the server > > > are in different time zones? If I run the server on my development box the > > > session does not time out like on the server. > > > > > > > > > Regards > > > Phil > > > > > > > > > On Wed, 2010-05-19 at 13:13 +0200, Hans H?bner wrote: > > > > > > Phil, > > > > > > are you sure that youre new value for *SESSION-MAX-TIME* is used by > > > your sessions? Try tracing HUNCHENTOOT::SESSION-TOO-OLD-P and check > > > the log file for entries saying "Session with ID too old". If > > > you see those messages in the log, or if > > > HUNCHENTOOT::SESSION-TOO-OLD-P returns a true value for a session, > > > your *SESSION-MAX-TIME* change has not been seen by Hunchentoot. > > > > > > One reason could be that you're changing the value of the global > > > variable after you started Hunchentoot in multi-threaded mode. In > > > that case, the changed value might not be picked up. > > > > > > Let us know how you proceed. > > > > > > -Hans > > > > > > On Wed, May 19, 2010 at 12:46, Phil Marneweck wrote: > > >> Hi > > >> > > >> Is there any thing more than *session-gc-frequency* and > > >> *session-max-time* that influences session time outs? > > >> > > >> Because it does not matter how high I set these values the session keeps > > >> on timing out with in a couple of minutes! > > >> > > >> Can those values be set at any time or do they have to be set before any > > >> acceptors are created? > > >> > > >> Any help would be much appreciated this is causing me major pain on a > > >> live site. > > >> > > >> > > >> > > >> > > >> > > >> > > >> _______________________________________________ > > >> tbnl-devel site list > > >> tbnl-devel at common-lisp.net > > >> http://common-lisp.net/mailman/listinfo/tbnl-devel > > >> > > > > > > _______________________________________________ > > > tbnl-devel site list > > > tbnl-devel at common-lisp.net > > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > > > > > > _______________________________________________ > > > tbnl-devel site list > > > tbnl-devel at common-lisp.net > > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From edi at agharta.de Thu May 20 09:23:59 2010 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 May 2010 11:23:59 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274330483.1658.168.camel@scatha> References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> Message-ID: On Thu, May 20, 2010 at 6:41 AM, Phil Marneweck wrote: > Thanx again for the help. You're welcome... :) > PS: How about some cross references in the documentation for > *session-gc-frequency*, *session-max-time* and > *use-remote-addr-for-sessions* just as a heads up for other people that > might stumble into this? Well, they are all mentioned in the same short chapter about sessions, and *use-remote-addr-for-sessions* is by default set to NIL. One should assume that users setting this value to T know what they're doing. Besides, I don't see any specific relation between, e.g., *session-gc-frequency* and *use-remote-addr-for-sessions*. Edi. From zaries at global.co.za Fri May 21 11:12:36 2010 From: zaries at global.co.za (Phil Marneweck) Date: Fri, 21 May 2010 13:12:36 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> Message-ID: <1274440356.1658.341.camel@scatha> Well after running fine for a while hunchentoot is again re-setting sessions at arbitrary intervals. I have closed down my lisp instance serveral times today and restarted everything. Everything will work for a while (5 to 45 minutes) and then fall apart. Once hunchentoot has killed sessions once, it does so every couple of minutes, some times under a minute. I have checked my code again looking for a place that I might be killing the sessions or setting the session to nil in any way but I have no such code. I set the following before creating any acceptors: (setf hunchentoot::*session-gc-frequency* nil) (setf hunchentoot::*session-max-time* 36000) (setf hunchentoot::*use-user-agent-for-sessions* nil) hunchentoot::*use-remote-addr-for-sessions* reports NIL I added a check to see what the (session-db *my-acceptor*) reports when I say hunchentoot "resets sessions" and it reports NIL. Before a reset (session-db *my-acceptor*) reports (8 .#). The only other thing that I can think might have an effect is that the site uses ssl but hunchentoot is not hangling the ssl I am forwarding from nginx to hunchentoot. Any suggestions? On Thu, 2010-05-20 at 11:23 +0200, Edi Weitz wrote: > On Thu, May 20, 2010 at 6:41 AM, Phil Marneweck wrote: > > > Thanx again for the help. > > You're welcome... :) > > > PS: How about some cross references in the documentation for > > *session-gc-frequency*, *session-max-time* and > > *use-remote-addr-for-sessions* just as a heads up for other people that > > might stumble into this? > > Well, they are all mentioned in the same short chapter about sessions, > and *use-remote-addr-for-sessions* is by default set to NIL. One > should assume that users setting this value to T know what they're > doing. Besides, I don't see any specific relation between, e.g., > *session-gc-frequency* and *use-remote-addr-for-sessions*. > > Edi. > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From zaries at global.co.za Fri May 21 11:29:31 2010 From: zaries at global.co.za (Phil Marneweck) Date: Fri, 21 May 2010 13:29:31 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274440356.1658.341.camel@scatha> References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> <1274440356.1658.341.camel@scatha> Message-ID: <1274441371.1658.346.camel@scatha> Some additional info: I am running the latest sbcl, hunchentoot and related code from clbuild as of Monday the 17th and my server is a virtual ubuntu 9.4 On Fri, 2010-05-21 at 13:12 +0200, Phil Marneweck wrote: > Well after running fine for a while hunchentoot is again re-setting > sessions at arbitrary intervals. > > I have closed down my lisp instance serveral times today and restarted > everything. Everything will work for a while (5 to 45 minutes) and > then fall apart. Once hunchentoot has killed sessions once, it does so > every couple of minutes, some times under a minute. > > I have checked my code again looking for a place that I might be > killing the sessions or setting the session to nil in any way but I > have no such code. > > I set the following before creating any acceptors: > > (setf hunchentoot::*session-gc-frequency* nil) > (setf hunchentoot::*session-max-time* 36000) > (setf hunchentoot::*use-user-agent-for-sessions* nil) > > hunchentoot::*use-remote-addr-for-sessions* reports NIL > > I added a check to see what the (session-db *my-acceptor*) reports > when I say hunchentoot "resets sessions" and it reports NIL. Before a > reset (session-db *my-acceptor*) reports (8 .#). > > The only other thing that I can think might have an effect is that the > site uses ssl but hunchentoot is not hangling the ssl I am forwarding > from nginx to hunchentoot. > > Any suggestions? > > > > On Thu, 2010-05-20 at 11:23 +0200, Edi Weitz wrote: > > > On Thu, May 20, 2010 at 6:41 AM, Phil Marneweck wrote: > > > > > Thanx again for the help. > > > > You're welcome... :) > > > > > PS: How about some cross references in the documentation for > > > *session-gc-frequency*, *session-max-time* and > > > *use-remote-addr-for-sessions* just as a heads up for other people that > > > might stumble into this? > > > > Well, they are all mentioned in the same short chapter about sessions, > > and *use-remote-addr-for-sessions* is by default set to NIL. One > > should assume that users setting this value to T know what they're > > doing. Besides, I don't see any specific relation between, e.g., > > *session-gc-frequency* and *use-remote-addr-for-sessions*. > > > > Edi. > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From hans.huebner at gmail.com Fri May 21 13:03:12 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Fri, 21 May 2010 15:03:12 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274440356.1658.341.camel@scatha> References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> <1274440356.1658.341.camel@scatha> Message-ID: Phil, did you make sure that it is actually Hunchentoot that "kills" your sessions? Does SESSION-TOO-OLD-P ever return T for a session that you've been using? Did you do some analysis on the Cookies headers that your server receives? Maybe your frontend somehow messes up the cookies. Did you look at the Hunchentoot log file? Any anomalies? Does it report something about sessions? Try disabling the session garbage collector completely by making it return without doing anything. >From what you write I have the impression that the problem is not within Hunchentoot itself. -Hans On Fri, May 21, 2010 at 13:12, Phil Marneweck wrote: > Well after running fine for a while hunchentoot is again re-setting sessions > at arbitrary intervals. > > I have closed down my lisp instance serveral times today and restarted > everything. Everything will work for a while (5 to 45 minutes) and then fall > apart. Once hunchentoot has killed sessions once, it does so every couple of > minutes, some times under a minute. > > I have checked my code again looking for a place that I might be killing the > sessions or setting the session to nil in any way but I have no such code. > > I set the following before creating any acceptors: > > (setf hunchentoot::*session-gc-frequency* nil) > (setf hunchentoot::*session-max-time* 36000) > (setf hunchentoot::*use-user-agent-for-sessions* nil) > > hunchentoot::*use-remote-addr-for-sessions* reports NIL > > I added a check to see what the (session-db *my-acceptor*) reports when I > say hunchentoot "resets sessions" and it reports NIL. Before a reset > (session-db *my-acceptor*) reports (8 .#). > > The only other thing that I can think might have an effect is that the site > uses ssl but hunchentoot is not hangling the ssl I am forwarding from nginx > to hunchentoot. > > Any suggestions? > > > > On Thu, 2010-05-20 at 11:23 +0200, Edi Weitz wrote: > > On Thu, May 20, 2010 at 6:41 AM, Phil Marneweck wrote: > >> Thanx again for the help. > > You're welcome... :) > >> PS: How about some cross references in the documentation for >> *session-gc-frequency*, *session-max-time* and >> *use-remote-addr-for-sessions* just as a heads up for other people that >> might stumble into this? > > Well, they are all mentioned in the same short chapter about sessions, > and *use-remote-addr-for-sessions* is by default set to NIL. One > should assume that users setting this value to T know what they're > doing. Besides, I don't see any specific relation between, e.g., > *session-gc-frequency* and *use-remote-addr-for-sessions*. > > Edi. > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > From zaries at global.co.za Fri May 21 15:35:17 2010 From: zaries at global.co.za (Phil Marneweck) Date: Fri, 21 May 2010 17:35:17 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> <1274440356.1658.341.camel@scatha> Message-ID: <1274456117.1658.355.camel@scatha> I switched on every logging option and added a hook to session-removal-hook (setf hunchentoot::*session-removal-hook* #'(lambda (session) (hunchentoot::log-message :info "Session-removal-hook ~A" session)) (setf hunchentoot::*message-log-pathname* "/home/phil/www/") (setf hunchentoot::*log-lisp-errors-p* t) (setf hunchentoot::*log-lisp-backtraces-p* t) (setf hunchentoot::*log-lisp-warnings-p* t) (setf hunchentoot::*lisp-warnings-log-level* :info) (setf hunchentoot::*lisp-errors-log-level* :info) And after about 16 minutes this gem came up in the log [2010-05-21 17:26:43 [INFO]] Session-removal-hook # [2010-05-21 17:26:43 [INFO]] Session-removal-hook # Attached find the full log for the session. Could invalid cookies cause a session gc in hunchentoot? Please advise on how I could track what causes the gc. Thank you very much for your patience. On Fri, 2010-05-21 at 15:03 +0200, Hans H?bner wrote: > Phil, > > did you make sure that it is actually Hunchentoot that "kills" your > sessions? Does SESSION-TOO-OLD-P ever return T for a session that > you've been using? Did you do some analysis on the Cookies headers > that your server receives? Maybe your frontend somehow messes up the > cookies. Did you look at the Hunchentoot log file? Any anomalies? > Does it report something about sessions? Try disabling the session > garbage collector completely by making it return without doing > anything. > > >From what you write I have the impression that the problem is not > within Hunchentoot itself. > > -Hans > > On Fri, May 21, 2010 at 13:12, Phil Marneweck wrote: > > Well after running fine for a while hunchentoot is again re-setting sessions > > at arbitrary intervals. > > > > I have closed down my lisp instance serveral times today and restarted > > everything. Everything will work for a while (5 to 45 minutes) and then fall > > apart. Once hunchentoot has killed sessions once, it does so every couple of > > minutes, some times under a minute. > > > > I have checked my code again looking for a place that I might be killing the > > sessions or setting the session to nil in any way but I have no such code. > > > > I set the following before creating any acceptors: > > > > (setf hunchentoot::*session-gc-frequency* nil) > > (setf hunchentoot::*session-max-time* 36000) > > (setf hunchentoot::*use-user-agent-for-sessions* nil) > > > > hunchentoot::*use-remote-addr-for-sessions* reports NIL > > > > I added a check to see what the (session-db *my-acceptor*) reports when I > > say hunchentoot "resets sessions" and it reports NIL. Before a reset > > (session-db *my-acceptor*) reports (8 .#). > > > > The only other thing that I can think might have an effect is that the site > > uses ssl but hunchentoot is not hangling the ssl I am forwarding from nginx > > to hunchentoot. > > > > Any suggestions? > > > > > > > > On Thu, 2010-05-20 at 11:23 +0200, Edi Weitz wrote: > > > > On Thu, May 20, 2010 at 6:41 AM, Phil Marneweck wrote: > > > >> Thanx again for the help. > > > > You're welcome... :) > > > >> PS: How about some cross references in the documentation for > >> *session-gc-frequency*, *session-max-time* and > >> *use-remote-addr-for-sessions* just as a heads up for other people that > >> might stumble into this? > > > > Well, they are all mentioned in the same short chapter about sessions, > > and *use-remote-addr-for-sessions* is by default set to NIL. One > > should assume that users setting this value to T know what they're > > doing. Besides, I don't see any specific relation between, e.g., > > *session-gc-frequency* and *use-remote-addr-for-sessions*. > > > > Edi. > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: hunchentoot.log Type: text/x-log Size: 9849 bytes Desc: not available URL: From hans.huebner at gmail.com Fri May 21 15:56:36 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Fri, 21 May 2010 17:56:36 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274456117.1658.355.camel@scatha> References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> <1274440356.1658.341.camel@scatha> <1274456117.1658.355.camel@scatha> Message-ID: Phil, session garbage collection is triggered (only) during request processing as a side effect of creating a new session. Sessions are only deleted when their max idle time has been reached. Invalid session cookies have no influence on the deletion, i.e. if an invalid session cookie is detected by Hunchentoot, a new session will be created. Expiry is then only run as a side effect. You'll have no option but read session.lisp yourself and try to make a better analysis. You may even find a bug in Hunchentoot, but from my perspective, I cannot see anything wrong. Print statements and tracing are your friend. -Hans On Fri, May 21, 2010 at 17:35, Phil Marneweck wrote: > I switched on every logging option and added a hook to session-removal-hook > > (setf hunchentoot::*session-removal-hook* #'(lambda (session) > (hunchentoot::log-message :info "Session-removal-hook ~A" session)) > (setf hunchentoot::*message-log-pathname* "/home/phil/www/") > (setf hunchentoot::*log-lisp-errors-p* t) > (setf hunchentoot::*log-lisp-backtraces-p* t) > (setf hunchentoot::*log-lisp-warnings-p* t) > (setf hunchentoot::*lisp-warnings-log-level* :info) > (setf hunchentoot::*lisp-errors-log-level* :info) > > And after about 16 minutes this gem came up in the log > > [2010-05-21 17:26:43 [INFO]] Session-removal-hook # > [2010-05-21 17:26:43 [INFO]] Session-removal-hook # > > Attached find the full log for the session. > > Could invalid cookies cause a session gc in hunchentoot? > > Please advise on how I could track what causes the gc. > > Thank you very much for your patience. > > > > On Fri, 2010-05-21 at 15:03 +0200, Hans H?bner wrote: > > Phil, > > did you make sure that it is actually Hunchentoot that "kills" your > sessions? Does SESSION-TOO-OLD-P ever return T for a session that > you've been using? Did you do some analysis on the Cookies headers > that your server receives? Maybe your frontend somehow messes up the > cookies. Did you look at the Hunchentoot log file? Any anomalies? > Does it report something about sessions? Try disabling the session > garbage collector completely by making it return without doing > anything. > > >From what you write I have the impression that the problem is not > within Hunchentoot itself. > > -Hans > > On Fri, May 21, 2010 at 13:12, Phil Marneweck wrote: >> Well after running fine for a while hunchentoot is again re-setting >> sessions >> at arbitrary intervals. >> >> I have closed down my lisp instance serveral times today and restarted >> everything. Everything will work for a while (5 to 45 minutes) and then >> fall >> apart. Once hunchentoot has killed sessions once, it does so every couple >> of >> minutes, some times under a minute. >> >> I have checked my code again looking for a place that I might be killing >> the >> sessions or setting the session to nil in any way but I have no such code. >> >> I set the following before creating any acceptors: >> >> (setf hunchentoot::*session-gc-frequency* nil) >> (setf hunchentoot::*session-max-time* 36000) >> (setf hunchentoot::*use-user-agent-for-sessions* nil) >> >> hunchentoot::*use-remote-addr-for-sessions* reports NIL >> >> I added a check to see what the (session-db *my-acceptor*) reports when I >> say hunchentoot "resets sessions" and it reports NIL. Before a reset >> (session-db *my-acceptor*) reports (8 .#). >> >> The only other thing that I can think might have an effect is that the >> site >> uses ssl but hunchentoot is not hangling the ssl I am forwarding from >> nginx >> to hunchentoot. >> >> Any suggestions? >> >> >> >> On Thu, 2010-05-20 at 11:23 +0200, Edi Weitz wrote: >> >> On Thu, May 20, 2010 at 6:41 AM, Phil Marneweck >> wrote: >> >>> Thanx again for the help. >> >> You're welcome... :) >> >>> PS: How about some cross references in the documentation for >>> *session-gc-frequency*, *session-max-time* and >>> *use-remote-addr-for-sessions* just as a heads up for other people that >>> might stumble into this? >> >> Well, they are all mentioned in the same short chapter about sessions, >> and *use-remote-addr-for-sessions* is by default set to NIL. One >> should assume that users setting this value to T know what they're >> doing. Besides, I don't see any specific relation between, e.g., >> *session-gc-frequency* and *use-remote-addr-for-sessions*. >> >> Edi. >> >> _______________________________________________ >> tbnl-devel site list >> tbnl-devel at common-lisp.net >> http://common-lisp.net/mailman/listinfo/tbnl-devel >> >> >> _______________________________________________ >> tbnl-devel site list >> tbnl-devel at common-lisp.net >> http://common-lisp.net/mailman/listinfo/tbnl-devel >> > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > From zaries at global.co.za Fri May 21 16:15:18 2010 From: zaries at global.co.za (Phil Marneweck) Date: Fri, 21 May 2010 18:15:18 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: References: <1274265969.31570.13.camel@scatha> <1274274823.1658.78.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> <1274440356.1658.341.camel@scatha> <1274456117.1658.355.camel@scatha> Message-ID: <1274458518.1658.358.camel@scatha> Ok, I will try. Just to put me on the right tract, why would hunchentoot kill ALL sessions in GC and not just he ones that might have expired because that is what is happening here? On Fri, 2010-05-21 at 17:56 +0200, Hans H?bner wrote: > Phil, > > session garbage collection is triggered (only) during request > processing as a side effect of creating a new session. Sessions are > only deleted when their max idle time has been reached. Invalid > session cookies have no influence on the deletion, i.e. if an invalid > session cookie is detected by Hunchentoot, a new session will be > created. Expiry is then only run as a side effect. > > You'll have no option but read session.lisp yourself and try to make a > better analysis. You may even find a bug in Hunchentoot, but from my > perspective, I cannot see anything wrong. Print statements and > tracing are your friend. > > -Hans > > On Fri, May 21, 2010 at 17:35, Phil Marneweck wrote: > > I switched on every logging option and added a hook to session-removal-hook > > > > (setf hunchentoot::*session-removal-hook* #'(lambda (session) > > (hunchentoot::log-message :info "Session-removal-hook ~A" session)) > > (setf hunchentoot::*message-log-pathname* "/home/phil/www/") > > (setf hunchentoot::*log-lisp-errors-p* t) > > (setf hunchentoot::*log-lisp-backtraces-p* t) > > (setf hunchentoot::*log-lisp-warnings-p* t) > > (setf hunchentoot::*lisp-warnings-log-level* :info) > > (setf hunchentoot::*lisp-errors-log-level* :info) > > > > And after about 16 minutes this gem came up in the log > > > > [2010-05-21 17:26:43 [INFO]] Session-removal-hook # > > [2010-05-21 17:26:43 [INFO]] Session-removal-hook # > > > > Attached find the full log for the session. > > > > Could invalid cookies cause a session gc in hunchentoot? > > > > Please advise on how I could track what causes the gc. > > > > Thank you very much for your patience. > > > > > > > > On Fri, 2010-05-21 at 15:03 +0200, Hans H?bner wrote: > > > > Phil, > > > > did you make sure that it is actually Hunchentoot that "kills" your > > sessions? Does SESSION-TOO-OLD-P ever return T for a session that > > you've been using? Did you do some analysis on the Cookies headers > > that your server receives? Maybe your frontend somehow messes up the > > cookies. Did you look at the Hunchentoot log file? Any anomalies? > > Does it report something about sessions? Try disabling the session > > garbage collector completely by making it return without doing > > anything. > > > > >From what you write I have the impression that the problem is not > > within Hunchentoot itself. > > > > -Hans > > > > On Fri, May 21, 2010 at 13:12, Phil Marneweck wrote: > >> Well after running fine for a while hunchentoot is again re-setting > >> sessions > >> at arbitrary intervals. > >> > >> I have closed down my lisp instance serveral times today and restarted > >> everything. Everything will work for a while (5 to 45 minutes) and then > >> fall > >> apart. Once hunchentoot has killed sessions once, it does so every couple > >> of > >> minutes, some times under a minute. > >> > >> I have checked my code again looking for a place that I might be killing > >> the > >> sessions or setting the session to nil in any way but I have no such code. > >> > >> I set the following before creating any acceptors: > >> > >> (setf hunchentoot::*session-gc-frequency* nil) > >> (setf hunchentoot::*session-max-time* 36000) > >> (setf hunchentoot::*use-user-agent-for-sessions* nil) > >> > >> hunchentoot::*use-remote-addr-for-sessions* reports NIL > >> > >> I added a check to see what the (session-db *my-acceptor*) reports when I > >> say hunchentoot "resets sessions" and it reports NIL. Before a reset > >> (session-db *my-acceptor*) reports (8 .#). > >> > >> The only other thing that I can think might have an effect is that the > >> site > >> uses ssl but hunchentoot is not hangling the ssl I am forwarding from > >> nginx > >> to hunchentoot. > >> > >> Any suggestions? > >> > >> > >> > >> On Thu, 2010-05-20 at 11:23 +0200, Edi Weitz wrote: > >> > >> On Thu, May 20, 2010 at 6:41 AM, Phil Marneweck > >> wrote: > >> > >>> Thanx again for the help. > >> > >> You're welcome... :) > >> > >>> PS: How about some cross references in the documentation for > >>> *session-gc-frequency*, *session-max-time* and > >>> *use-remote-addr-for-sessions* just as a heads up for other people that > >>> might stumble into this? > >> > >> Well, they are all mentioned in the same short chapter about sessions, > >> and *use-remote-addr-for-sessions* is by default set to NIL. One > >> should assume that users setting this value to T know what they're > >> doing. Besides, I don't see any specific relation between, e.g., > >> *session-gc-frequency* and *use-remote-addr-for-sessions*. > >> > >> Edi. > >> > >> _______________________________________________ > >> tbnl-devel site list > >> tbnl-devel at common-lisp.net > >> http://common-lisp.net/mailman/listinfo/tbnl-devel > >> > >> > >> _______________________________________________ > >> tbnl-devel site list > >> tbnl-devel at common-lisp.net > >> http://common-lisp.net/mailman/listinfo/tbnl-devel > >> > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From hans.huebner at gmail.com Fri May 21 16:40:27 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Fri, 21 May 2010 18:40:27 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274458518.1658.358.camel@scatha> References: <1274265969.31570.13.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> <1274440356.1658.341.camel@scatha> <1274456117.1658.355.camel@scatha> <1274458518.1658.358.camel@scatha> Message-ID: On Fri, May 21, 2010 at 18:15, Phil Marneweck wrote: > Just to put me on the right tract, why would hunchentoot kill ALL sessions > in GC and not just he ones that might have expired because that is what is > happening here? (defun session-gc () "Removes sessions from the current session database which are too old - see SESSION-TOO-OLD-P." (with-session-lock-held ((session-db-lock *acceptor*)) (setf (session-db *acceptor*) (loop for id-session-pair in (session-db *acceptor*) for (nil . session) = id-session-pair when (session-too-old-p session) do (funcall *session-removal-hook* session) else collect id-session-pair))) (values)) i.e. you need to read the source. -Hans From zaries at global.co.za Fri May 21 17:03:40 2010 From: zaries at global.co.za (Phil Marneweck) Date: Fri, 21 May 2010 19:03:40 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: References: <1274265969.31570.13.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> <1274440356.1658.341.camel@scatha> <1274456117.1658.355.camel@scatha> <1274458518.1658.358.camel@scatha> Message-ID: <1274461420.1658.366.camel@scatha> Ok thanx put some log entries in there and will report back. On Fri, 2010-05-21 at 18:40 +0200, Hans H?bner wrote: > On Fri, May 21, 2010 at 18:15, Phil Marneweck wrote: > > Just to put me on the right tract, why would hunchentoot kill ALL sessions > > in GC and not just he ones that might have expired because that is what is > > happening here? > > (defun session-gc () > "Removes sessions from the current session database which are too > old - see SESSION-TOO-OLD-P." > (with-session-lock-held ((session-db-lock *acceptor*)) > (setf (session-db *acceptor*) > (loop for id-session-pair in (session-db *acceptor*) > for (nil . session) = id-session-pair > when (session-too-old-p session) > do (funcall *session-removal-hook* session) > else > collect id-session-pair))) > (values)) > > i.e. you need to read the source. > > -Hans > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From zaries at global.co.za Fri May 21 18:47:13 2010 From: zaries at global.co.za (Phil Marneweck) Date: Fri, 21 May 2010 20:47:13 +0200 Subject: [hunchentoot-devel] Session Time Out - HELP! In-Reply-To: <1274461420.1658.366.camel@scatha> References: <1274265969.31570.13.camel@scatha> <1274280115.1658.134.camel@scatha> <1274330483.1658.168.camel@scatha> <1274440356.1658.341.camel@scatha> <1274456117.1658.355.camel@scatha> <1274458518.1658.358.camel@scatha> <1274461420.1658.366.camel@scatha> Message-ID: <1274467633.1658.391.camel@scatha> Well after driving myself and this mailing list nuts with this issue it turns out it is my bad... A new colleague of mine (one I am training) uploaded a piece of code to our server without checking it into our repository, this piece of offending code had a hunchentoot::reset-sessions in it and I have been greping againts the local code base to find any resets , after adding some more logging to sessions.lisp on the server i was able to find the offending code on the server. I appologise for the frantic messages and thank the members of this list for there patience and help ... once again!!! By the way thanx for the wonderful work you do on huncentoot, we appreciate every bit. Yours Humbly ....*grovel* ...*grovel* On Fri, 2010-05-21 at 19:03 +0200, Phil Marneweck wrote: > Ok thanx put some log entries in there and will report back. > > On Fri, 2010-05-21 at 18:40 +0200, Hans H?bner wrote: > > > On Fri, May 21, 2010 at 18:15, Phil Marneweck wrote: > > > Just to put me on the right tract, why would hunchentoot kill ALL sessions > > > in GC and not just he ones that might have expired because that is what is > > > happening here? > > > > (defun session-gc () > > "Removes sessions from the current session database which are too > > old - see SESSION-TOO-OLD-P." > > (with-session-lock-held ((session-db-lock *acceptor*)) > > (setf (session-db *acceptor*) > > (loop for id-session-pair in (session-db *acceptor*) > > for (nil . session) = id-session-pair > > when (session-too-old-p session) > > do (funcall *session-removal-hook* session) > > else > > collect id-session-pair))) > > (values)) > > > > i.e. you need to read the source. > > > > -Hans > > > > _______________________________________________ > > tbnl-devel site list > > tbnl-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/tbnl-devel > > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From swm at itasoftware.com Thu May 27 14:57:15 2010 From: swm at itasoftware.com (Scott McKay) Date: Thu, 27 May 2010 10:57:15 -0400 Subject: [hunchentoot-devel] 'max-threads' behavior for Hunchentoot Message-ID: <96F4A9B1-5603-4DE1-9144-415C9251DAA5@itasoftware.com> Here are some changes I made to implement 'max-threads' semantics for Hunchentoot. I'd like [some version of] this functionality to be installed into Hunchentoot, so that it is a better behaved multi-threaded web server. A few notes: - The function conditionalized out with #+++potentially-faster-way is meant to be a hint as to how we might refuse the connection without invoking the overhead of accepting the over-the-limit connection. It might be slightly faster, but I don't know if I like the idea of constantly closing and reopening the listener. - 'pooled-thread-per-connection-taskmaster' is just a stub right now, although it provides a useful hook for future work. The idea is to use a thread pool, but on my box, thread creation takes about 250 usec, so it's not clear to me that it's worth the effort, particularly since Bordeaux threads doesn't have the necessary functionality to do it correctly. - 'handle-incoming-connection' on 'one-thread-per-connection-taskmaster' should really try to generate an HTTP 503 error, instead of just closing the connection. I tried several things to make this happen, but nothing seemed to work properly. It seems a shame to have to open the client connection, suck in the whole request, etc etc, just to do this. Is there a better way? Is there some sort of "connection refused" we can do at the socket level? Your review comments and any advice on the third issue would be greatly appreciated. Thanks! --Scott Modified: trunk/qres/lisp/libs/hunchentoot/packages.lisp ============================================================================== --- trunk/qres/lisp/libs/hunchentoot/packages.lisp (original) +++ trunk/qres/lisp/libs/hunchentoot/packages.lisp Thu May 27 10:31:21 2010 @@ -192,7 +192,6 @@ "MIME-TYPE" "NEXT-SESSION-ID" "NO-CACHE" - "ONE-THREAD-PER-CONNECTION-TASKMASTER" "PARAMETER" "PARAMETER-ERROR" "POST-PARAMETER" @@ -250,7 +249,6 @@ "SET-COOKIE" "SET-COOKIE*" "SHUTDOWN" - "SINGLE-THREADED-TASKMASTER" #-:hunchentoot-no-ssl "SSL-ACCEPTOR" "SSL-P" "START" @@ -259,7 +257,12 @@ "STOP" "TASKMASTER" "TASKMASTER-ACCEPTOR" - "URL-DECODE" + "SINGLE-THREADED-TASKMASTER" + "ONE-THREAD-PER-CONNECTION-TASKMASTER" + "POOLED-THREAD-PER-CONNECTION-TASKMASTER" + "INCREMENT-TASKMASTER-THREAD-COUNT" + "DECREMENT-TASKMASTER-THREAD-COUNT" + "URL-DECODE" "URL-ENCODE" "USER-AGENT")) Modified: trunk/qres/lisp/libs/hunchentoot/acceptor.lisp ============================================================================== --- trunk/qres/lisp/libs/hunchentoot/acceptor.lisp (original) +++ trunk/qres/lisp/libs/hunchentoot/acceptor.lisp Thu May 27 10:31:21 2010 @@ -86,7 +86,7 @@ reason to change this to NIL.") (input-chunking-p :initarg :input-chunking-p :accessor acceptor-input-chunking-p - :documentation "A generalized boolean denoting + :documentation "A generalized boolean denoting whether the acceptor may use chunked encoding for input, i.e. when accepting request bodies from the client. The default is T and there's usually no reason to change this to NIL.") @@ -117,8 +117,7 @@ process different from the one where START was called.") #-:lispworks (listen-socket :accessor acceptor-listen-socket - :documentation "The socket listening for incoming -connections.") + :documentation "The socket listening for incoming connections.") (acceptor-shutdown-p :initform nil :accessor acceptor-shutdown-p :documentation "A flag that makes the acceptor @@ -349,9 +348,12 @@ ;; the default is to always answer "no" nil) -;; usocket implementation + +;;; usocket implementation #-:lispworks +(progn + (defmethod start-listening ((acceptor acceptor)) (setf (acceptor-listen-socket acceptor) (usocket:socket-listen (or (acceptor-address acceptor) @@ -361,26 +363,61 @@ :element-type '(unsigned-byte 8))) (values)) -#-:lispworks (defmethod accept-connections ((acceptor acceptor)) (usocket:with-server-socket (listener (acceptor-listen-socket acceptor)) (loop - (when (acceptor-shutdown-p acceptor) - (return)) - (when (usocket:wait-for-input listener :timeout +new-connection-wait-time+) - (handler-case - (when-let (client-connection (usocket:socket-accept listener)) - (set-timeouts client-connection - (acceptor-read-timeout acceptor) - (acceptor-write-timeout acceptor)) - (handle-incoming-connection (acceptor-taskmaster acceptor) - client-connection)) - ;; ignore condition - (usocket:connection-aborted-error ())))))) + (when (acceptor-shutdown-p acceptor) + (return)) + (when (usocket:wait-for-input listener :timeout +new-connection-wait-time+) + (handler-case + (let ((taskmaster (acceptor-taskmaster acceptor))) + (when-let (client-connection (usocket:socket-accept listener)) + (set-timeouts client-connection + (acceptor-read-timeout acceptor) + (acceptor-write-timeout acceptor)) + ;; This will bail if the taskmaster has reached its thread limit + (handle-incoming-connection taskmaster client-connection))) + ;; Ignore the error + (usocket:connection-aborted-error ())))))) + +#+++potentially-faster-way +(defmethod accept-connections ((acceptor acceptor)) + (loop + (usocket:with-server-socket (listener (acceptor-listen-socket acceptor)) + (loop named waiter doing + (when (acceptor-shutdown-p acceptor) + (return-from accept-connections)) + (when (usocket:wait-for-input listener :timeout +new-connection-wait-time+) + (handler-case + (let ((taskmaster (acceptor-taskmaster acceptor))) + ;; Optimization to avoid creating the client connection: + ;; if the taskmaster has reached its thread limit, just close + ;; and reopen the listener socket, and don't even call 'accept' + (when (and (taskmaster-max-threads taskmaster) + (> (taskmaster-thread-count taskmaster) (taskmaster-max-threads taskmaster))) + (when-let (handler (taskmaster-too-many-threads-handler taskmaster)) + (funcall handler taskmaster listener)) + (usocket:socket-close listener) ;close the listener + (setq listener nil) + (start-listening acceptor) ;and start up a new one + (return-from waiter)) + (when-let (client-connection (usocket:socket-accept listener)) + (set-timeouts client-connection + (acceptor-read-timeout acceptor) + (acceptor-write-timeout acceptor)) + ;; This will bail if the taskmaster has reached its thread limit + (handle-incoming-connection taskmaster client-connection))) + ;; Ignore the error + (usocket:connection-aborted-error ()))))))) + +) ;#-:lispworks -;; LispWorks implementation + +;;; LispWorks implementation #+:lispworks +(progn + (defmethod start-listening ((acceptor acceptor)) (multiple-value-bind (listener-process startup-condition) (comm:start-up-server :service (acceptor-port acceptor) @@ -398,8 +435,8 @@ ;; is made :function (lambda (handle) (unless (acceptor-shutdown-p acceptor) - (handle-incoming-connection - (acceptor-taskmaster acceptor) handle))) + (let ((taskmaster (acceptor-taskmaster acceptor))) + (handle-incoming-connection taskmaster client-connection)))) ;; wait until the acceptor was successfully started ;; or an error condition is returned :wait t) @@ -409,11 +446,13 @@ (setf (acceptor-process acceptor) listener-process) (values))) -#+:lispworks (defmethod accept-connections ((acceptor acceptor)) (mp:process-unstop (acceptor-process acceptor)) nil) +) ;#+:lispworks + + (defun list-request-dispatcher (request) "The default request dispatcher which selects a request handler based on a list of individual request dispatchers all of which can Modified: trunk/qres/lisp/libs/hunchentoot/taskmaster.lisp ============================================================================== --- trunk/qres/lisp/libs/hunchentoot/taskmaster.lisp (original) +++ trunk/qres/lisp/libs/hunchentoot/taskmaster.lisp Thu May 27 10:31:21 2010 @@ -62,6 +62,21 @@ might terminate all threads that are currently associated with it. This function is called by the acceptor's STOP method.")) +;; Default method +(defmethod taskmaster-max-threads ((taskmaster taskmaster)) + nil) + +;; Default method +(defmethod taskmaster-thread-count ((taskmaster taskmaster)) + 0) + +(defmethod increment-taskmaster-thread-count ((taskmaster taskmaster)) + nil) + +(defmethod decrement-taskmaster-thread-count ((taskmaster taskmaster)) + nil) + + (defclass single-threaded-taskmaster (taskmaster) () (:documentation "A taskmaster that runs synchronously in the thread @@ -80,25 +95,95 @@ ;; in a single-threaded environment we just call PROCESS-CONNECTION (process-connection (taskmaster-acceptor taskmaster) socket)) + (defclass one-thread-per-connection-taskmaster (taskmaster) (#-:lispworks - (acceptor-process :accessor acceptor-process - :documentation "A process that accepts incoming -connections and hands them off to new processes for request -handling.")) + (acceptor-process + :accessor acceptor-process + :documentation + "A process that accepts incoming connections and hands them off to new processes + for request handling.") + (create-thread-function + :initarg :create-thread-function + :initform 'create-taskmaster-thread + :accessor taskmaster-create-thread-function + :documentation + "Function called to create the handler thread; + takes two arguments, the taskmaster and the socket") + ;; Support for bounding the number of threads we'll create + (max-threads + :type (or integer null) + :initarg :max-threads + :initform nil + :accessor taskmaster-max-threads) + (thread-count + :type integer + :initform 0 + :accessor taskmaster-thread-count) + (thread-count-lock + :initform (bt:make-lock "taskmaster-thread-count") + :accessor taskmaster-thread-count-lock) + (worker-thread-name-format + :type (or string null) + :initarg :worker-thread-name-format + :initform "hunchentoot-worker-~A" + :accessor taskmaster-worker-thread-name-format) + (too-many-threads-handler + :initarg :too-many-threads-handler + :initform nil + :accessor taskmaster-too-many-threads-handler + :documentation + "Function called with two arguments, the taskmaster and the socket, + when too many threads reached, just prior to closing the connection")) + (:default-initargs + :too-many-threads-handler 'log-too-many-threads) (:documentation "A taskmaster that starts one thread for listening -to incoming requests and one thread for each incoming connection. +to incoming requests and one new thread for each incoming connection. +If 'max-threads' is supplied, the number of threads is limited to that. This is the default taskmaster implementation for multi-threaded Lisp implementations.")) -;; usocket implementation +(defmethod increment-taskmaster-thread-count ((taskmaster one-thread-per-connection-taskmaster)) + (when (taskmaster-max-threads taskmaster) + (bt:with-lock-held ((taskmaster-thread-count-lock taskmaster)) + (incf (taskmaster-thread-count taskmaster))))) + +(defmethod decrement-taskmaster-thread-count ((taskmaster one-thread-per-connection-taskmaster)) + (when (taskmaster-max-threads taskmaster) + (bt:with-lock-held ((taskmaster-thread-count-lock taskmaster)) + (decf (taskmaster-thread-count taskmaster))))) + +(defun log-too-many-threads (taskmaster socket) + (declare (ignore socket)) + (let* ((acceptor (taskmaster-acceptor taskmaster)) + (logger (and acceptor (acceptor-message-logger acceptor)))) + (when logger + (funcall logger :warning "Can't handle a new connection, too many threads already")))) + + +;;--- If thread creation is too slow, it would be worth finishing this +;;--- For now, it's just a synonym for 'one-thread-per-connection-taskmaster' +(defclass pooled-thread-per-connection-taskmaster (one-thread-per-connection-taskmaster) + ((create-thread-function + :initarg :create-thread-function + :initform 'create-taskmaster-thread + :accessor taskmaster-create-thread-function + :documentation + "Function called to create the handler thread")) + (:documentation "A taskmaster that starts one thread for listening +to incoming requests and then uses a thread pool for each incoming connection. +If 'max-threads' is supplied, the number of threads is limited to that.")) + + +;;; usocket implementation #-:lispworks +(progn + (defmethod shutdown ((taskmaster taskmaster)) taskmaster) -#-:lispworks (defmethod shutdown ((taskmaster one-thread-per-connection-taskmaster)) ;; just wait until the acceptor process has finished, then return (loop @@ -107,16 +192,39 @@ (sleep 1)) taskmaster) -#-:lispworks (defmethod execute-acceptor ((taskmaster one-thread-per-connection-taskmaster)) (setf (acceptor-process taskmaster) - (bt:make-thread (lambda () - (accept-connections (taskmaster-acceptor taskmaster))) - :name (format nil "Hunchentoot listener \(~A:~A)" - (or (acceptor-address (taskmaster-acceptor taskmaster)) "*") - (acceptor-port (taskmaster-acceptor taskmaster)))))) + (bt:make-thread + (lambda () + (accept-connections (taskmaster-acceptor taskmaster))) + :name (format nil "hunchentoot-listener-~A:~A" + (or (acceptor-address (taskmaster-acceptor taskmaster)) "*") + (acceptor-port (taskmaster-acceptor taskmaster)))))) + +(defmethod handle-incoming-connection ((taskmaster one-thread-per-connection-taskmaster) socket) + ;; Only take lock if necessary + (if (taskmaster-max-threads taskmaster) + (if (< (taskmaster-thread-count taskmaster) (taskmaster-max-threads taskmaster)) + (progn + (increment-taskmaster-thread-count taskmaster) + (funcall (taskmaster-create-thread-function taskmaster) taskmaster socket)) + (progn + (when-let (handler (taskmaster-too-many-threads-handler taskmaster)) + (funcall handler taskmaster socket)) + ;; Just close the socket, which will effectively abort the request + ;;--- It sure would be nice to be able to generate an HTTP 503 error, + ;;--- but I just can't seem to get that to work properly + (usocket:socket-close socket))) + (funcall (taskmaster-create-thread-function taskmaster) taskmaster socket))) + +(defun create-taskmaster-thread (taskmaster socket) + (bt:make-thread + (lambda () + (multiple-value-prog1 + (process-connection (taskmaster-acceptor taskmaster) socket) + (decrement-taskmaster-thread-count taskmaster))) + :name (format nil (taskmaster-worker-thread-name-format taskmaster) (client-as-string socket)))) -#-:lispworks (defun client-as-string (socket) "A helper function which returns the client's address and port as a string and tries to act robustly in the presence of network problems." @@ -127,15 +235,14 @@ (usocket:vector-quad-to-dotted-quad address) port)))) -#-:lispworks -(defmethod handle-incoming-connection ((taskmaster one-thread-per-connection-taskmaster) socket) - (bt:make-thread (lambda () - (process-connection (taskmaster-acceptor taskmaster) socket)) - :name (format nil "Hunchentoot worker \(client: ~A)" (client-as-string socket)))) +) ;#-:lispworks + -;; LispWorks implementation +;;; LispWorks implementation #+:lispworks +(progn + (defmethod shutdown ((taskmaster taskmaster)) (when-let (process (acceptor-process (taskmaster-acceptor taskmaster))) ;; kill the main acceptor process, see LW documentation for @@ -143,20 +250,38 @@ (mp:process-kill process)) taskmaster) -#+:lispworks (defmethod execute-acceptor ((taskmaster one-thread-per-connection-taskmaster)) (accept-connections (taskmaster-acceptor taskmaster))) -#+:lispworks -(defmethod handle-incoming-connection ((taskmaster one-thread-per-connection-taskmaster) handle) +(defmethod handle-incoming-connection ((taskmaster one-thread-per-connection-taskmaster) socket) (incf *worker-counter*) ;; check if we need to perform a global GC (when (and *cleanup-interval* (zerop (mod *worker-counter* *cleanup-interval*))) (when *cleanup-function* (funcall *cleanup-function*))) - (mp:process-run-function (format nil "Hunchentoot worker \(client: ~{~A:~A~})" - (multiple-value-list - (get-peer-address-and-port handle))) - nil #'process-connection - (taskmaster-acceptor taskmaster) handle)) + (if (taskmaster-max-threads taskmaster) + (if (< (taskmaster-thread-count taskmaster) (taskmaster-max-threads taskmaster)) + (progn + (increment-taskmaster-thread-count taskmaster) + (funcall (taskmaster-create-thread-function taskmaster) taskmaster socket)) + ;; With any luck, we never get this far if we've exceeded the thread count + ;; "Good" implementations of 'accept-connections' won't even accept connection requests + (progn + (when-let (handler (taskmaster-too-many-threads-handler taskmaster)) + (funcall handler taskmaster socket)) + (usocket:socket-close socket))) + (funcall (taskmaster-create-thread-function taskmaster) taskmaster socket))) + +(defun create-taskmaster-thread (taskmaster socket) + (flet ((process (taskmaster sock) + (multiple-value-prog1 + (process-connection (taskmaster-acceptor taskmaster) socket) + (decrement-taskmaster-thread-count taskmaster)))) + (mp:process-run-function (format nil "hunchentoot-worker-{~A:~A~})" + (multiple-value-list + (get-peer-address-and-port socket))) + nil #'process taskmaster socket))) + +) ;#+:lispworks + From hans.huebner at gmail.com Sun May 30 09:56:06 2010 From: hans.huebner at gmail.com (=?ISO-8859-1?Q?Hans_H=FCbner?=) Date: Sun, 30 May 2010 11:56:06 +0200 Subject: [hunchentoot-devel] 'max-threads' behavior for Hunchentoot In-Reply-To: <96F4A9B1-5603-4DE1-9144-415C9251DAA5@itasoftware.com> References: <96F4A9B1-5603-4DE1-9144-415C9251DAA5@itasoftware.com> Message-ID: Hi Scott, first off, thank you for taking the time to improve Hunchentoot and for sending a proposed patch. Please have a look at http://weitz.de/patches.html before submitting your next patch for review. In particular, it makes reviews much easier if there is documentation about what the patch means to do. On Thu, May 27, 2010 at 16:57, Scott McKay wrote: > A few notes: > ?- The function conditionalized out with #+++potentially-faster-way > ? is meant to be a hint as to how we might refuse the connection > ? without invoking the overhead of accepting the over-the-limit > ? connection. ?It might be slightly faster, but I don't know if > ? I like the idea of constantly closing and reopening the listener. I don't like the idea, as it opens up a race condition which will result in connections being rejected under high load. > ?- 'handle-incoming-connection' on 'one-thread-per-connection-taskmaster' > ? ?should really try to generate an HTTP 503 error, instead of just > ? ?closing the connection. ?I tried several things to make this happen, > ? ?but nothing seemed to work properly. ?It seems a shame to have to > ? ?open the client connection, suck in the whole request, etc etc, > ? ?just to do this. ?Is there a better way? ?Is there some sort of > ? ?"connection refused" we can do at the socket level? I don't see a need to read the request in order to reply with a 503 error. If the server can't dispatch the request because a resource limit has been hit, there is nothing wrong with just sending a 503 reply without looking at the request at all. Berkeley sockets do not provide a means to reject individual pending connections. Further comments inline: > > --Scott > > > Modified: trunk/qres/lisp/libs/hunchentoot/packages.lisp > ============================================================================== > --- trunk/qres/lisp/libs/hunchentoot/packages.lisp ? ? ?(original) > +++ trunk/qres/lisp/libs/hunchentoot/packages.lisp ? ? ?Thu May 27 10:31:21 2010 > @@ -192,7 +192,6 @@ > ? ? ? ? ? "MIME-TYPE" > ? ? ? ? ? "NEXT-SESSION-ID" > ? ? ? ? ? "NO-CACHE" > - ? ? ? ? ? "ONE-THREAD-PER-CONNECTION-TASKMASTER" > ? ? ? ? ? "PARAMETER" > ? ? ? ? ? "PARAMETER-ERROR" > ? ? ? ? ? "POST-PARAMETER" > @@ -250,7 +249,6 @@ > ? ? ? ? ? "SET-COOKIE" > ? ? ? ? ? "SET-COOKIE*" > ? ? ? ? ? "SHUTDOWN" > - ? ? ? ? ? "SINGLE-THREADED-TASKMASTER" > ? ? ? ? ? #-:hunchentoot-no-ssl "SSL-ACCEPTOR" > ? ? ? ? ? "SSL-P" > ? ? ? ? ? "START" > @@ -259,7 +257,12 @@ > ? ? ? ? ? "STOP" > ? ? ? ? ? "TASKMASTER" > ? ? ? ? ? "TASKMASTER-ACCEPTOR" > - ? ? ? ? ? "URL-DECODE" > + ? ? ? ? ? "SINGLE-THREADED-TASKMASTER" > + ? ? ? ? ? "ONE-THREAD-PER-CONNECTION-TASKMASTER" > + ? ? ? ? ? "POOLED-THREAD-PER-CONNECTION-TASKMASTER" > + ? ? ? ? ? "INCREMENT-TASKMASTER-THREAD-COUNT" > + ? ? ? ? ?"DECREMENT-TASKMASTER-THREAD-COUNT" > + ? ? ? ? ?"URL-DECODE" > ? ? ? ? ? "URL-ENCODE" > ? ? ? ? ? "USER-AGENT")) > > Modified: trunk/qres/lisp/libs/hunchentoot/acceptor.lisp > ============================================================================== > --- trunk/qres/lisp/libs/hunchentoot/acceptor.lisp ? ? ?(original) > +++ trunk/qres/lisp/libs/hunchentoot/acceptor.lisp ? ? ?Thu May 27 10:31:21 2010 > @@ -86,7 +86,7 @@ > reason to change this to NIL.") > ? (input-chunking-p :initarg :input-chunking-p > ? ? ? ? ? ? ? ? ? ? :accessor acceptor-input-chunking-p > - ? ? ? ? ? ? ? ? ? ? ?:documentation "A generalized boolean denoting > + ? ? ? ? ? ? ? ? ? ?:documentation "A generalized boolean denoting > whether the acceptor may use chunked encoding for input, i.e. when > accepting request bodies from the client. ?The default is T and > there's usually no reason to change this to NIL.") > @@ -117,8 +117,7 @@ > process different from the one where START was called.") > ? #-:lispworks > ? (listen-socket :accessor acceptor-listen-socket > - ? ? ? ? ? ? ? ? ?:documentation "The socket listening for incoming > -connections.") > + ? ? ? ? ? ? ? ? ?:documentation "The socket listening for incoming connections.") > ? (acceptor-shutdown-p :initform nil > ? ? ? ? ? ? ? ? ? ? ? ?:accessor acceptor-shutdown-p > ? ? ? ? ? ? ? ? ? ? ? ?:documentation "A flag that makes the acceptor > @@ -349,9 +348,12 @@ > ?;; the default is to always answer "no" > ?nil) > > -;; usocket implementation > + > +;;; usocket implementation > > #-:lispworks > +(progn What is this progn needed for? > + > (defmethod start-listening ((acceptor acceptor)) > ?(setf (acceptor-listen-socket acceptor) > ? ? ? ?(usocket:socket-listen (or (acceptor-address acceptor) > @@ -361,26 +363,61 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? :element-type '(unsigned-byte 8))) > ?(values)) > > -#-:lispworks > (defmethod accept-connections ((acceptor acceptor)) > ?(usocket:with-server-socket (listener (acceptor-listen-socket acceptor)) > ? ?(loop > - ? ? (when (acceptor-shutdown-p acceptor) > - ? ? ? (return)) > - ? ? (when (usocket:wait-for-input listener :timeout +new-connection-wait-time+) > - ? ? ? (handler-case > - ? ? ? ? ? (when-let (client-connection (usocket:socket-accept listener)) > - ? ? ? ? ? ? (set-timeouts client-connection > - ? ? ? ? ? ? ? ? ? ? ? ? ? (acceptor-read-timeout acceptor) > - ? ? ? ? ? ? ? ? ? ? ? ? ? (acceptor-write-timeout acceptor)) > - ? ? ? ? ? ? (handle-incoming-connection (acceptor-taskmaster acceptor) > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? client-connection)) > - ? ? ? ? ;; ignore condition > - ? ? ? ? (usocket:connection-aborted-error ())))))) > + ? ? ?(when (acceptor-shutdown-p acceptor) > + ? ? ? (return)) > + ? ? ?(when (usocket:wait-for-input listener :timeout +new-connection-wait-time+) > + ? ? ? (handler-case > + ? ? ? ? ? (let ((taskmaster (acceptor-taskmaster acceptor))) > + ? ? ? ? ? ? (when-let (client-connection (usocket:socket-accept listener)) > + ? ? ? ? ? ? ? (set-timeouts client-connection > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? (acceptor-read-timeout acceptor) > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? (acceptor-write-timeout acceptor)) > + ? ? ? ? ? ? ? ;; This will bail if the taskmaster has reached its thread limit > + ? ? ? ? ? ? ? (handle-incoming-connection taskmaster client-connection))) > + ? ? ? ? ;; Ignore the error > + ? ? ? ? (usocket:connection-aborted-error ())))))) > + > +#+++potentially-faster-way > +(defmethod accept-connections ((acceptor acceptor)) > + ?(loop > + ? ?(usocket:with-server-socket (listener (acceptor-listen-socket acceptor)) > + ? ? ?(loop named waiter doing > + ? ? ? (when (acceptor-shutdown-p acceptor) > + ? ? ? ? (return-from accept-connections)) > + ? ? ? (when (usocket:wait-for-input listener :timeout +new-connection-wait-time+) > + ? ? ? ? (handler-case > + ? ? ? ? ? ? (let ((taskmaster (acceptor-taskmaster acceptor))) > + ? ? ? ? ? ? ? ;; Optimization to avoid creating the client connection: > + ? ? ? ? ? ? ? ;; if the taskmaster has reached its thread limit, just close > + ? ? ? ? ? ? ? ;; and reopen the listener socket, and don't even call 'accept' > + ? ? ? ? ? ? ? (when (and (taskmaster-max-threads taskmaster) > + ? ? ? ? ? ? ? ? ? ? ? ? ?(> (taskmaster-thread-count taskmaster) (taskmaster-max-threads taskmaster))) > + ? ? ? ? ? ? ? ? (when-let (handler (taskmaster-too-many-threads-handler taskmaster)) > + ? ? ? ? ? ? ? ? ? (funcall handler taskmaster listener)) > + ? ? ? ? ? ? ? ? (usocket:socket-close listener) ? ? ? ;close the listener > + ? ? ? ? ? ? ? ? (setq listener nil) > + ? ? ? ? ? ? ? ? (start-listening acceptor) ? ? ? ? ? ?;and start up a new one > + ? ? ? ? ? ? ? ? (return-from waiter)) > + ? ? ? ? ? ? ? (when-let (client-connection (usocket:socket-accept listener)) > + ? ? ? ? ? ? ? ? (set-timeouts client-connection > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (acceptor-read-timeout acceptor) > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (acceptor-write-timeout acceptor)) > + ? ? ? ? ? ? ? ? ;; This will bail if the taskmaster has reached its thread limit > + ? ? ? ? ? ? ? ? (handle-incoming-connection taskmaster client-connection))) > + ? ? ? ? ? ;; Ignore the error > + ? ? ? ? ? (usocket:connection-aborted-error ()))))))) > + > +) ? ? ?;#-:lispworks > > -;; LispWorks implementation > + > +;;; LispWorks implementation > > #+:lispworks > +(progn > + Don't use progn here. Conditionalize the individual top-level forms. Otherwise, automatic reindentation will screw up the source file. > (defmethod start-listening ((acceptor acceptor)) > ?(multiple-value-bind (listener-process startup-condition) > ? ? ?(comm:start-up-server :service (acceptor-port acceptor) > @@ -398,8 +435,8 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ?;; is made > ? ? ? ? ? ? ? ? ? ? ? ? ? ?:function (lambda (handle) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(unless (acceptor-shutdown-p acceptor) > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(handle-incoming-connection > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (acceptor-taskmaster acceptor) handle))) > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(let ((taskmaster (acceptor-taskmaster acceptor))) > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (handle-incoming-connection taskmaster client-connection)))) > ? ? ? ? ? ? ? ? ? ? ? ? ? ?;; wait until the acceptor was successfully started > ? ? ? ? ? ? ? ? ? ? ? ? ? ?;; or an error condition is returned > ? ? ? ? ? ? ? ? ? ? ? ? ? ?:wait t) > @@ -409,11 +446,13 @@ > ? ?(setf (acceptor-process acceptor) listener-process) > ? ?(values))) > > -#+:lispworks > (defmethod accept-connections ((acceptor acceptor)) > ?(mp:process-unstop (acceptor-process acceptor)) > ?nil) > > +) ? ? ?;#+:lispworks > + > + > (defun list-request-dispatcher (request) > ?"The default request dispatcher which selects a request handler > based on a list of individual request dispatchers all of which can > > Modified: trunk/qres/lisp/libs/hunchentoot/taskmaster.lisp > ============================================================================== > --- trunk/qres/lisp/libs/hunchentoot/taskmaster.lisp ? ?(original) > +++ trunk/qres/lisp/libs/hunchentoot/taskmaster.lisp ? ?Thu May 27 10:31:21 2010 > @@ -62,6 +62,21 @@ > might terminate all threads that are currently associated with it. > This function is called by the acceptor's STOP method.")) > > +;; Default method > +(defmethod taskmaster-max-threads ((taskmaster taskmaster)) > + ?nil) > + > +;; Default method > +(defmethod taskmaster-thread-count ((taskmaster taskmaster)) > + ?0) > + > +(defmethod increment-taskmaster-thread-count ((taskmaster taskmaster)) > + ?nil) > + > +(defmethod decrement-taskmaster-thread-count ((taskmaster taskmaster)) > + ?nil) > + > + > (defclass single-threaded-taskmaster (taskmaster) > ?() > ?(:documentation "A taskmaster that runs synchronously in the thread > @@ -80,25 +95,95 @@ > ?;; in a single-threaded environment we just call PROCESS-CONNECTION > ?(process-connection (taskmaster-acceptor taskmaster) socket)) > > + > (defclass one-thread-per-connection-taskmaster (taskmaster) > ?(#-:lispworks > - ? (acceptor-process :accessor acceptor-process > - ? ? ? ? ? ? ? ? ? ? :documentation "A process that accepts incoming > -connections and hands them off to new processes for request > -handling.")) > + ? (acceptor-process > + ? ?:accessor acceptor-process > + ? ?:documentation > + ? ?"A process that accepts incoming connections and hands them off to new processes > + ? ? for request handling.") > + ? (create-thread-function > + ? ?:initarg :create-thread-function > + ? ?:initform 'create-taskmaster-thread > + ? ?:accessor taskmaster-create-thread-function > + ? ?:documentation > + ? ?"Function called to create the handler thread; > + ? ? takes two arguments, the taskmaster and the socket") > + ? ;; Support for bounding the number of threads we'll create > + ? (max-threads > + ? ?:type (or integer null) > + ? ?:initarg :max-threads > + ? ?:initform nil > + ? ?:accessor taskmaster-max-threads) > + ? (thread-count > + ? ?:type integer > + ? ?:initform 0 > + ? ?:accessor taskmaster-thread-count) > + ? (thread-count-lock > + ? ?:initform (bt:make-lock "taskmaster-thread-count") > + ? ?:accessor taskmaster-thread-count-lock) > + ? (worker-thread-name-format > + ? ?:type (or string null) > + ? ?:initarg :worker-thread-name-format > + ? ?:initform "hunchentoot-worker-~A" > + ? ?:accessor taskmaster-worker-thread-name-format) > + ? (too-many-threads-handler > + ? ?:initarg :too-many-threads-handler > + ? ?:initform nil > + ? ?:accessor taskmaster-too-many-threads-handler > + ? ?:documentation > + ? ?"Function called with two arguments, the taskmaster and the socket, > + ? ? when too many threads reached, just prior to closing the connection")) > + ?(:default-initargs > + ? :too-many-threads-handler 'log-too-many-threads) > ?(:documentation "A taskmaster that starts one thread for listening > -to incoming requests and one thread for each incoming connection. > +to incoming requests and one new thread for each incoming connection. > +If 'max-threads' is supplied, the number of threads is limited to that. Why did you chose to implement create-threads-function and too-many-threads-handler as slots rather than generic functions? The latter seems much more natural to me. > > This is the default taskmaster implementation for multi-threaded Lisp > implementations.")) > > -;; usocket implementation > +(defmethod increment-taskmaster-thread-count ((taskmaster one-thread-per-connection-taskmaster)) > + ?(when (taskmaster-max-threads taskmaster) > + ? ?(bt:with-lock-held ((taskmaster-thread-count-lock taskmaster)) > + ? ? ?(incf (taskmaster-thread-count taskmaster))))) > + > +(defmethod decrement-taskmaster-thread-count ((taskmaster one-thread-per-connection-taskmaster)) > + ?(when (taskmaster-max-threads taskmaster) > + ? ?(bt:with-lock-held ((taskmaster-thread-count-lock taskmaster)) > + ? ? ?(decf (taskmaster-thread-count taskmaster))))) > + > +(defun log-too-many-threads (taskmaster socket) > + ?(declare (ignore socket)) > + ?(let* ((acceptor (taskmaster-acceptor taskmaster)) > + ? ? ? ?(logger ? (and acceptor (acceptor-message-logger acceptor)))) > + ? ?(when logger > + ? ? ?(funcall logger :warning "Can't handle a new connection, too many threads already")))) > + > + > +;;--- If thread creation is too slow, it would be worth finishing this > +;;--- For now, it's just a synonym for 'one-thread-per-connection-taskmaster' > +(defclass pooled-thread-per-connection-taskmaster (one-thread-per-connection-taskmaster) > + ?((create-thread-function > + ? ?:initarg :create-thread-function > + ? ?:initform 'create-taskmaster-thread > + ? ?:accessor taskmaster-create-thread-function > + ? ?:documentation > + ? ?"Function called to create the handler thread")) > + ?(:documentation "A taskmaster that starts one thread for listening > +to incoming requests and then uses a thread pool for each incoming connection. > +If 'max-threads' is supplied, the number of threads is limited to that.")) > + > + > +;;; usocket implementation > > #-:lispworks > +(progn > + Another top-level progn that should go. > (defmethod shutdown ((taskmaster taskmaster)) > ?taskmaster) > > -#-:lispworks > (defmethod shutdown ((taskmaster one-thread-per-connection-taskmaster)) > ?;; just wait until the acceptor process has finished, then return > ?(loop > @@ -107,16 +192,39 @@ > ? (sleep 1)) > ?taskmaster) > > -#-:lispworks > (defmethod execute-acceptor ((taskmaster one-thread-per-connection-taskmaster)) > ?(setf (acceptor-process taskmaster) > - ? ? ? ?(bt:make-thread (lambda () > - ? ? ? ? ? ? ? ? ? ? ? ? ?(accept-connections (taskmaster-acceptor taskmaster))) > - ? ? ? ? ? ? ? ? ? ? ? ?:name (format nil "Hunchentoot listener \(~A:~A)" > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(or (acceptor-address (taskmaster-acceptor taskmaster)) "*") > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(acceptor-port (taskmaster-acceptor taskmaster)))))) > + ? ? ? ?(bt:make-thread > + ? ? ? ?(lambda () > + ? ? ? ? ?(accept-connections (taskmaster-acceptor taskmaster))) > + ? ? ? ?:name (format nil "hunchentoot-listener-~A:~A" > + ? ? ? ? ? ? ? ? ? ? ?(or (acceptor-address (taskmaster-acceptor taskmaster)) "*") > + ? ? ? ? ? ? ? ? ? ? ?(acceptor-port (taskmaster-acceptor taskmaster)))))) > + > +(defmethod handle-incoming-connection ((taskmaster one-thread-per-connection-taskmaster) socket) > + ?;; Only take lock if necessary > + ?(if (taskmaster-max-threads taskmaster) > + ? ?(if (< (taskmaster-thread-count taskmaster) (taskmaster-max-threads taskmaster)) > + ? ? ?(progn > + ? ? ? (increment-taskmaster-thread-count taskmaster) > + ? ? ? (funcall (taskmaster-create-thread-function taskmaster) taskmaster socket)) > + ? ? ?(progn > + ? ? ? (when-let (handler (taskmaster-too-many-threads-handler taskmaster)) > + ? ? ? ? (funcall handler taskmaster socket)) > + ? ? ? ;; Just close the socket, which will effectively abort the request > + ? ? ? ;;--- It sure would be nice to be able to generate an HTTP 503 error, > + ? ? ? ;;--- but I just can't seem to get that to work properly > + ? ? ? (usocket:socket-close socket))) Please do not use (if .. (progn ..) (progn ..)). Use cond instead or refactor. In this case, I'd think that the maintenance of the thread count could be moved into the generic function that creates the thread, once the callback slot has been replaced by a gf. > + ? ?(funcall (taskmaster-create-thread-function taskmaster) taskmaster socket))) > + > +(defun create-taskmaster-thread (taskmaster socket) > + ?(bt:make-thread > + ? (lambda () > + ? ? (multiple-value-prog1 > + ? ? ? ?(process-connection (taskmaster-acceptor taskmaster) socket) > + ? ? ? (decrement-taskmaster-thread-count taskmaster))) > + ? :name (format nil (taskmaster-worker-thread-name-format taskmaster) (client-as-string socket)))) > > -#-:lispworks > (defun client-as-string (socket) > ?"A helper function which returns the client's address and port as a > string and tries to act robustly in the presence of network problems." > @@ -127,15 +235,14 @@ > ? ? ? ? ? ? ?(usocket:vector-quad-to-dotted-quad address) > ? ? ? ? ? ? ?port)))) > > -#-:lispworks > -(defmethod handle-incoming-connection ((taskmaster one-thread-per-connection-taskmaster) socket) > - ?(bt:make-thread (lambda () > - ? ? ? ? ? ? ? ? ? ?(process-connection (taskmaster-acceptor taskmaster) socket)) > - ? ? ? ? ? ? ? ? ?:name (format nil "Hunchentoot worker \(client: ~A)" (client-as-string socket)))) > +) ? ? ?;#-:lispworks > + > > -;; LispWorks implementation > +;;; LispWorks implementation > > #+:lispworks > +(progn > + Another top-level progn (not going to point at those if there are any more, please let them all go). > (defmethod shutdown ((taskmaster taskmaster)) > ?(when-let (process (acceptor-process (taskmaster-acceptor taskmaster))) > ? ?;; kill the main acceptor process, see LW documentation for > @@ -143,20 +250,38 @@ > ? ?(mp:process-kill process)) > ?taskmaster) > > -#+:lispworks > (defmethod execute-acceptor ((taskmaster one-thread-per-connection-taskmaster)) > ?(accept-connections (taskmaster-acceptor taskmaster))) > > -#+:lispworks > -(defmethod handle-incoming-connection ((taskmaster one-thread-per-connection-taskmaster) handle) > +(defmethod handle-incoming-connection ((taskmaster one-thread-per-connection-taskmaster) socket) > ?(incf *worker-counter*) > ?;; check if we need to perform a global GC > ?(when (and *cleanup-interval* > ? ? ? ? ? ? (zerop (mod *worker-counter* *cleanup-interval*))) > ? ?(when *cleanup-function* > ? ? ?(funcall *cleanup-function*))) > - ?(mp:process-run-function (format nil "Hunchentoot worker \(client: ~{~A:~A~})" > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (multiple-value-list > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(get-peer-address-and-port handle))) > - ? ? ? ? ? ? ? ? ? ? ? ? ? nil #'process-connection > - ? ? ? ? ? ? ? ? ? ? ? ? ? (taskmaster-acceptor taskmaster) handle)) > + ?(if (taskmaster-max-threads taskmaster) > + ? ?(if (< (taskmaster-thread-count taskmaster) (taskmaster-max-threads taskmaster)) > + ? ? ?(progn > + ? ? ? (increment-taskmaster-thread-count taskmaster) > + ? ? ? (funcall (taskmaster-create-thread-function taskmaster) taskmaster socket)) > + ? ? ?;; With any luck, we never get this far if we've exceeded the thread count > + ? ? ?;; "Good" implementations of 'accept-connections' won't even accept connection requests > + ? ? ?(progn > + ? ? ? (when-let (handler (taskmaster-too-many-threads-handler taskmaster)) > + ? ? ? ? (funcall handler taskmaster socket)) > + ? ? ? (usocket:socket-close socket))) > + ? ?(funcall (taskmaster-create-thread-function taskmaster) taskmaster socket))) Another (if ... (progn ..)) that should be improved. > + > +(defun create-taskmaster-thread (taskmaster socket) > + ?(flet ((process (taskmaster sock) > + ? ? ? ? ?(multiple-value-prog1 > + ? ? ? ? ? ? ?(process-connection (taskmaster-acceptor taskmaster) socket) > + ? ? ? ? ? ?(decrement-taskmaster-thread-count taskmaster)))) > + ? ?(mp:process-run-function (format nil "hunchentoot-worker-{~A:~A~})" > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(multiple-value-list > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (get-peer-address-and-port socket))) > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?nil #'process taskmaster socket))) > + > +) ? ? ?;#+:lispworks > + > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel >