[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