[Stackless] stacklesssocket.py problems

Arnar Birgisson arnarbi at gmail.com
Fri Jun 22 22:19:42 CEST 2007


Hi all,

I'm writing a WSGI server for Stackless, using stacklesssocket.
Basically, this is the loop that dispatches the requests:


def _accept_loop(self):
    while self.running:
        s, addr = self.socket.accept()
        print "accepted socket %r" % s
        if not self.running:
            return

        environ = self.environ.copy()
        # cut out some envionr["..."] = ... stuff

        conn = self.ConnectionClass(s, self.wsgi_app, environ)
        def comm():
            try:
                print "in try"
                conn.communicate()
            finally:
                print "in finally"
                conn.close()
        tasklet(comm)()
        # do we need to yield here or will the socket.accept be enough?

conn.communicate parses the request and does all the heavy lifting.

Now, as long as I run this with max one concurrent requests,
everything is fine. But as soon as I up the concurrency to 2 requests,
stacklesssocket blows up because .sendall(...) is being called after
.close() (which is done in the finally-block above through
conn.close()).

I'm not sure how to debug this, but for starters, I added some print
statements. First, this is how two serialized requests are handled
successfully:
(requests generated with "ab -n 2 -c 1 ...")

ss stands for stacklesssocket

accepted socket <stacklesssocket object at 0x00C9EFD0>
in try
<ss.dispatcher connected 127.0.0.1:4649 at 0xccd878> socket.recv()
<ss.dispatcher connected 127.0.0.1:4649 at 0xccd878> socket.sendall() 126 bytes
<ss..dispatcher connected 127.0.0.1:4649 at 0xccd878> socket.sendall() 13 bytes
in finally
<ss..dispatcher connected 127.0.0.1:4649 at 0xccd878> socket.close()
accepted socket <ss..stacklesssocket object at 0x00C9EDB0>
in try
<ss.dispatcher connected 127.0.0.1:4650 at 0xccda08> socket.recv()
<ss.dispatcher connected 127.0.0.1:4650 at 0xccda08> socket.sendall() 126 bytes
<ss.dispatcher connected 127.0.0.1:4650 at 0xccda08> socket.sendall() 13 bytes
in finally
<ss.dispatcher connected 127.0.0.1:4650 at 0xccda08> socket.close()


This looks just fine. However, here's how it looks if I up the
concurrency to two requests (ab -n 2 -c 2):

accepted socket <ss.stacklesssocket object at 0x00C9EFD0>
in try
<ss.dispatcher connected 127.0.0.1:4659 at 0xccd878> socket.recv()
<ss.dispatcher connected 127.0.0.1:4659 at 0xccd878> socket.sendall() 126 bytes
accepted socket <ss.stacklesssocket object at 0x00C9ED30>
<ss.dispatcher connected 127.0.0.1:4659 at 0xccd878> socket.sendall() 13 bytes
in try
<ss.dispatcher connected 127.0.0.1:4660 at 0xccdb20> socket.recv()
<ss.dispatcher connected 127.0.0.1:4660 at 0xccdb20> socket.sendall() 126 bytes
<ss.dispatcher connected 127.0.0.1:4659 at 0xccd878> socket.close()
in finally
<ss.dispatcher connected 127.0.0.1:4660 at 0xccdb20> socket.close()  <-- ERROR!
<ss.dispatcher 127.0.0.1:4660 at 0xccdb20> socket.sendall() 13 bytes
<ss.dispatcher 127.0.0.1:4660 at 0xccdb20> socket.sendall() 647 bytes
in finally
<ss.dispatcher 127.0.0.1:4660 at 0xccdb20> socket.close()
Traceback (most recent call last):
  File "stacklesswsgi\test\simpleapp.py", line 12, in <module>
    s.start()
  File "C:\G÷gn\Forritun\stackless-cp\cherrypy\stacklesswsgi\__init__.py",
line 539, in start
    stackless.run()
  File "C:\G÷gn\Forritun\stackless-cp\cherrypy\stacklesswsgi\__init__.py",
line 563, in comm
    conn.communicate()
  File "C:\G÷gn\Forritun\stackless-cp\cherrypy\stacklesswsgi\__init__.py",
line 503, in communicate
    req.simple_response("500 Internal Server Error", format_exc())
  File "C:\G÷gn\Forritun\stackless-cp\cherrypy\stacklesswsgi\__init__.py",
line 341, in simple_response
    self.sendall("".join(buf))
  File "C:\G÷gn\Forritun\stackless-cp\cherrypy\stacklesswsgi\stacklesssocket.py",
line 177, in sendall
    self.sendBuffer += data
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'str'



Now, it seems that when the first socket is closed - the second one is
closed as well! However, the conn object that calls close on the first
socket doesn't even have a reference to the second one - so I ruled
out that this is happening somewhere in that object.

Any ideas?

Arnar

_______________________________________________
Stackless mailing list
Stackless at stackless.com
http://www.stackless.com/mailman/listinfo/stackless



More information about the Stackless mailing list