2016-12-08 2 views
0

У меня есть приложение торнадо, которое запускает процесс без торнадо с tornado.process.Subprocess (в частности, ansible-playbook). У меня есть плагин обратного вызова в ansible-playbook, который запускает запросы базы данных на разных этапах. Из плагина я хочу использовать ту же библиотеку tornado_mysql, которую я использую в своем процессе торнадо. Я был в состоянии сделать это с помощью метода run_sync() смерча:Как использовать tornado_mysql из сценария python без торнадо?

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 также вилки нового потока для каждого хоста, к которому он подключается.

Вопрос, как я могу избавиться от этой ошибки?

ответ

0

Вы не можете делиться IOLoops по темам, это то, что вы делаете, позвонив по номеру 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)) 
+0

Это было точно так же, спасибо! –

Смежные вопросы