FSX / momoko

Wraps (asynchronous) Psycopg2 for Tornado.
http://momoko.61924.nl/
Other
363 stars 73 forks source link

Exception connection reuse bug #44

Closed miiza closed 10 years ago

miiza commented 11 years ago

I am new to Python and Tornado and I am not sure if this is a bug or I am doing some mistake. I have source code where I send SQL to PostgreSQL database and get back an exception, I catch it and send to the browser appropriate json - everything is quite OK. If I wait 10 seconds until connection cleanup, I get a new connection from pool and everything is OK again. But if I wait only 2 seconds I get unexpected error "Cannot send error response after headers written". Following is minimal source code that is able to reproduce the error:

#!/usr/bin/env python

import sys
import traceback

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado import gen

import psycopg2
import psycopg2.extras
import momoko

class TestHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    @gen.engine
    def get(self):
        try:
            cursor = yield gen.Task(self.application.db["nameservice"].execute, "select 1/0", {})
        except Exception as err:
            self.write({"err": "message"})
            self.finish()

def main():
    try:
        tornado.options.parse_command_line()
        routes = [
            (r'/test', TestHandler),
        ]
        application = tornado.web.Application(
            routes,
            debug=True,
            cookie_secret='bla bla'
        )

        application.db = {
            "nameservice": momoko.AsyncClient({
                'host': "localhost",
                'database': "nameservice",
                'user': "miiza",
                'password': "aaaaaaaaaaa",
                'min_conn': 0,
                'max_conn': 25,
                'cleanup_timeout': 8,
                'connection_factory': psycopg2.extras.NamedTupleConnection
            })
        }

        http_server = tornado.httpserver.HTTPServer(application)
        http_server.listen(8888)
        print "Tornado web server now runs."
        tornado.ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        print('Exit')

if __name__ == '__main__':
    main()

After first run everything is quite OK, exception was cought by my exception handler and the request is finished:

[I 130303 23:07:47 web:1462] 304 GET /test (127.0.0.1) 33.01ms

But when I send from my browser the same request after 2 seconds I get this error. It seems like if the exception hangs in the connection:

[E 130303 23:07:48 web:1085] Uncaught exception GET /test (127.0.0.1)
    HTTPRequest(protocol='http', host='localhost:8888', method='GET', uri='/test', version='HTTP/1.1', remote_ip='127.0.0.1', body='', headers={'Accept-Language': 'cs,en-us;q=0.7,en;q=0.3', 'Accept-Encoding': 'gzip, deflate', 'Host': 'localhost:8888', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'If-None-Match': '"62e84d336c5973652977bb0379ea846f163bcfaf"'})
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1021, in _stack_context_handle_exception
        raise_exc_info((type, value, traceback))
      File "/usr/local/lib/python2.7/dist-packages/tornado/stack_context.py", line 232, in wrapped
        callback(*args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/momoko/pools.py", line 313, in _io_callback
        state = self._conn.poll()
    DataError: division by zero

[E 130303 23:07:48 web:739] Cannot send error response after headers written

So, it is strange. I think my exception handler should catch the database exception anytime I send request from my browser. But the reality is that in case of db connection reuse it is not true. It seems like if connection which an exception went through becomes ill and breaks it completely.

haizaar commented 10 years ago

Please try with the latest master and reopen if still relevant.