Liam Paris
Liam Paris

Reputation: 75

GeneratorExit issue in Tornado

I'm currently getting this error. I'm confused because from what I can tell Generator Exit just gets called whenever a generator finishes, but I have a ton of other Generators inheriting this class that do not call this error. Am I setting the Generator up properly? or is there some implicit code I'm not taking into account that is calling close()?

"error": "Traceback (most recent call last):\n  File \"/stashboard/source/stashboard/checkers.py\", line 29, in run\n    yield self.check()\nGeneratorExit\n",

the code where this yield statement is called:

class Checker():

    def __init__(self,  event, frequency, params):
        self.event = event
        self.frequency = frequency
        self.params = params

    @gen.coroutine
    def run(self):
        """ Run check method every <frequency> seconds
        """
        while True:
            try:
                yield self.check()
            except GeneratorExit:
                logging.info("EXCEPTION")
                raise GeneratorExit
            except:
                data = {
                    'status': events.STATUS_ERROR,
                    'error': traceback.format_exc()
                }
                yield self.save(data)
            yield gen.sleep(self.frequency)

    @gen.coroutine
    def check(self):
        pass

    @gen.coroutine
    def save(self, data):
        yield events.save(self.event, data)

and this is the code that is inheriting from it:

class PostgreChecker(Checker):
    # checks list of Post
    formatter = 'stashboard.formatters.PostgreFormatter'

    def __init__(self, event, frequency, params):
        super().__init__(event, frequency, params)
        self.clients = []
        for DB in configuration["postgre"]:
            # setup and create connections to PG servers.
            postgreUri = queries.uri(DB["host"], DB["port"], DB["dbName"],
                                     DB["userName"], DB["password"])
            # creates actual link to DB
            client = queries.TornadoSession(postgreUri)
            # starts connection
            client.host = DB["host"]
            self.clients.append(client)

    @gen.coroutine
    def check(self):

        for client in self.clients:
            try:
                yield client.validate()
                self.save({'host': client.host,
                               'status': events.STATUS_OK})
            except (ConnectionError, AutoReconnect, ConnectionFailure):
                self.save({'host': client.host,
                           'status': events.STATUS_FAIL})

Upvotes: 1

Views: 256

Answers (2)

Liam Paris
Liam Paris

Reputation: 75

the specific issue here was that my db cursors were not automatically re-connecting. I was using the queries library, but switched over to momoko and the issue is gone

Upvotes: 0

Ben Darnell
Ben Darnell

Reputation: 22154

Tornado never calls close() on your generators, but the garbage collector does (starting in Python 3.4 I think). How is checker.run() called? Use IOLoop.spawn_callback() for fire-and-forget coroutines; this will keep a reference to them and allow them to keep running indefinitely.

Upvotes: 1

Related Questions