【问题标题】:GeneratorExit issue in TornadoTornado 中的 GeneratorExit 问题
【发布时间】:2016-10-27 13:30:27
【问题描述】:

我目前收到此错误。我很困惑,因为据我所知,只要生成器完成,Generator Exit 就会被调用,但是我有很多其他继承这个类的生成器不会调用这个错误。我是否正确设置了发电机?还是有一些我没有考虑到调用 close() 的隐式代码?

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

这个yield语句被调用的代码:

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)

这是继承自它的代码:

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})

【问题讨论】:

  • @gen.coroutine 中,你总是需要让子协程调用。您在最后一个方法(两次)中有 self.save(...) 而不是 yield self.save(...)

标签: python-3.x tornado psycopg2 yield coroutine


【解决方案1】:

Tornado 不会在您的生成器上调用 close(),但垃圾收集器会调用(我认为是从 Python 3.4 开始)。 checker.run() 怎么称呼?使用IOLoop.spawn_callback() 处理即发即弃的协程;这将保留对它们的引用并允许它们无限期地运行。

【讨论】:

  • 是的,它在while true 循环中运行,我如何使用spawn_callback()?我应该运行 self.check() 作为其中的回调吗?或者之后调用 spawn
  • IOLoop.current().spawn_callback(f),其中f 可能是带有调用checker.run()while True 循环的函数。
【解决方案2】:

这里的具体问题是我的数据库游标没有自动重新连接。我正在使用queries 库,但切换到momoko 并且问题消失了

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 2018-11-14
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多