如何从非龙卷风 python 脚本中使用 tornado_mysql?
How can I use tornado_mysql from a non tornado python script?
我有一个龙卷风应用程序,它使用 tornado.process.Subprocess
(特别是 ansible-playbook
)启动非龙卷风进程。我在 ansible-playbook
中有一个回调插件,可以在不同阶段运行数据库查询。从插件中,我想使用我在 tornado 进程中使用的相同 tornado_mysql
库。我能够使用龙卷风的 run_sync()
方法做到这一点:
callback_plugin.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))
db.py:
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
也会为它连接的每个主机派生一个新线程。
我的问题是,如何消除该错误?
您不能跨线程共享 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))
我有一个龙卷风应用程序,它使用 tornado.process.Subprocess
(特别是 ansible-playbook
)启动非龙卷风进程。我在 ansible-playbook
中有一个回调插件,可以在不同阶段运行数据库查询。从插件中,我想使用我在 tornado 进程中使用的相同 tornado_mysql
库。我能够使用龙卷风的 run_sync()
方法做到这一点:
callback_plugin.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))
db.py:
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
也会为它连接的每个主机派生一个新线程。
我的问题是,如何消除该错误?
您不能跨线程共享 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))