[Lispweb] Spurious socket errors in Araneida (and a fix)
Bob Hutchison
hutch at recursive.ca
Thu Jul 14 08:21:19 CDT 2005
Hi,
I believe I mentioned sometime way back that when connecting to an
Araneida server running in LispWorks on OS/X that frequent and
apparently spurious error messages indicating some kind of socket
problem were being printed. Safari caused many more errors than
FireFox, wget none at all. These things were happening at some high
frequency (Safari very close to 1 error per real request, Firefox maybe
1 of 4).
Anyway, the messages were beginning to be annoying so I tried to track
down the problem. What was happening was that in
read-request-from-stream there was an error. I wrapped the call to
read-line in a handler and dealt with the comm::socket-error that
lispworks was providing. I also prevented the handling of the now null
request. I then modified the do-it function in with-accept-flets to not
do-it if read-request-from-stream returned nil.
Messages gone.
I don't know if this problem exists in any other configuration. I also
don't know what specific condition is raised for other implementations
(so the handler-case in read-request-from-stream is pretty spartan).
Cheers,
Bob
---- somewhere in daemon.lisp --------
(defun read-request-from-stream (listener stream)
(let ((first-line nil))
(handler-case (setf first-line (read-line stream nil nil))
#+lispworks(comm::socket-error (condition)
(progn
(setf first-line nil))))
(when first-line
(let ((default-hostname (when (slot-boundp listener
'default-hostname)
(http-listener-default-hostname
listener))))
(read-request-from-stream/guts first-line default-hostname
stream)))))
---- somewhere in http-listener.lisp --------
(defmacro with-accept-flets (&body body)
`(labels ((do-it (listener s)
(let ((r (read-request-from-stream listener s)))
(when r
(handler-case
(handle-request-using-listener
listener (http-listener-handler listener) r)
(response-sent () nil)
(http-error (c)
(request-send-error r (http-error-code
c)
(http-error-message
c)))))))
(accept (listener)
(listener-accept-stream listener)))
(with-simple-restart
(abort-response "Abort this response and answer another request")
;; expectation is that socket-accept will not block, because we
;; are invoked when select() says something is ready. we really
;; ought to set the master socket non-blocking to be sure.
(let ((*debugger-hook* #'handler-debugger-hook))
, at body))))
More information about the lispweb
mailing list