如何从非tornado python脚本使用tornado\u mysql?

2024-04-19 17:27:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个tornado应用程序,它用tornado.process.Subprocess(特别是ansible-playbook)启动一个非tornado进程。我在ansible-playbook中有一个回调插件,它在不同的阶段运行数据库查询。从插件中,我想使用我在tornado进程中使用的tornado_mysql库。我用龙卷风的run_sync()方法做到了这一点:

回拨_插件.py地址:

import db.py
from tornado import ioloop
io_loop = ioloop.IOLoop.instance()
def playbook_on_play_start(self, play):
    io_loop.run_sync(lambda: db.update_job_play(job_id, play))

你知道吗双倍地址:

def get_conn():
    return pools.Pool(
        connect_kwargs={
            'host': settings.get('mysql_host'),
            'port': settings.get('mysql_port'),
            'user': settings.get('mysql_username'),
            'passwd': settings.get('mysql_password'),
            'db': settings.get('mysql_database_name'),
            'charset': 'utf8mb4',
            'init_command': 'SET NAMES \'utf8mb4\'',
            'cursorclass': DictCursor
        },
        max_idle_connections=settings.get('mysql_max_idle_connections'),
        max_open_connections=settings.get('mysql_open_connections')
    )

@tornado.gen.coroutine
def update_job_play(job_id, play):
    sql = """
    UPDATE `job`
    SET `current_play` = %(play)s
    WHERE `id` = %(job_id)s
    """
    yield get_conn().execute(sql, {
        'job_id': job_id,
        'play': play})

它正常工作,数据库也更新了,但我发现这个错误:

 ERROR:tornado.application:Exception in callback None        
 Traceback (most recent call last):
    File "/usr/local/lib/python2.7/site-packages/tornado/ioloop.py", line 882, in start
      fd_obj, handler_func = self._handlers[fd]
  KeyError: 13
  ERROR:tornado.application:Exception in callback None
  Traceback (most recent call last):
    File "/usr/local/lib/python2.7/site-packages/tornado/ioloop.py", line 882, in start
      fd_obj, handler_func = self._handlers[fd]
  KeyError: 13
  ERROR:tornado.application:Exception in callback None

我发现:Tornado IOLoop Exception in callback None in Celery worker这似乎是相关的。ansible-playbook是一个独立于主tornado应用程序的进程,但是ansible_playbook还为它连接到的每个主机派生一个新线程。你知道吗

我的问题是,我该如何消除这个错误?你知道吗


Tags: inpyidplaygetsettingscallbackmysql
1条回答
网友
1楼 · 发布于 2024-04-19 17:27:34

你不能跨线程共享IOLoops,这就是你在playbook线程中调用IOLoop.instance()所做的。相反,每次创建一个新的IOLoop

def playbook_on_play_start(self, play):
    with contextlib.closing(tornado.ioloop.IOLoop()) as io_loop:
        io_loop.run_sync(lambda: db.update_job_play(job_id, play))

相关问题 更多 >