[Zope] - Zope dies under mysterious circumstances

Andy Dustman adustman@comstar.net
Fri, 11 Dec 1998 16:21:20 -0500 (EST)


I may have found the problem, although I really haven't replicated the
problem in Zope. Rather, I found this was happening with another app of
mine that uses the BaseHTTPServer.HTTPServer class. Examine
ZopeHTTPServer.NonThreadingHTTPServer.handle_request:

    def handle_request(self):
        """Handle one request, possibly blocking."""
        request, client_address = self.get_request() # BOOM!
        if self.verify_request(request, client_address):
            try:
                self.process_request(request, client_address)
            except SystemExit:
                self.handle_error(request, client_address)
                sys.exit(0)
            except:
                self.handle_error(request, client_address)

If an exception is raised during the self.get_request() call, the server
dies. What exceptions can happen? Well, get_request(), which is being
inherited from way down in SocketServer.TCPServer, is simply returning
self.socket.accept(). As it turs out, I have seen socket.error raised for
"Peer reset connection". Probably this or some other socket.error is what
mysterious killed Zope.

What I don't understand, looking a little further down at the
ThreadingHTTPServer, is why does it not have a similar handle_request
method (it replicates server_bind)? Proposed fix:

class NonThreadingHTTPServer(BaseHTTPServer.HTTPServer):
    "The normal HTTPServer with some socket tweaks"

    def server_bind(self):
        self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        return BaseHTTPServer.HTTPServer.server_bind(self)

    def handle_request(self):
        """Handle one request, possibly blocking."""
	request, client_address = None, None
	try:
            request, client_address = self.get_request()
            if self.verify_request(request, client_address):
                self.process_request(request, client_address)
        except SystemExit:
            self.handle_error(request, client_address)
            sys.exit(0)
        except:
            self.handle_error(request, client_address)

class ThreadingHTTPServer(SocketServer.ThreadingMixIn,
	                  NonThreadingHTTPServer): pass

I have tested this lightly and it appears to work. Both with and with -t
threading option.

Performance, BTW, is quite good, considering I'm testing on an old 80MHz
486 with 40MB RAM...

-- 
Andy Dustman                    You should always say "spam" and "eggs"
ComStar Communications Corp.                 instead of "foo" and "bar"
(706) 549-7689 | PGP KeyID=0xC72F3F1D   in Python examples. (Mark Lutz)