2016-12-08 8 views
0

나는 비 토네이도 과정을 tornado.process.Subprocess (특히 ansible-playbook)으로 시작하는 토네이도 응용 프로그램을 가지고 있습니다. 다양한 단계에서 데이터베이스 쿼리를 실행하는 ansible-playbook에 콜백 플러그인이 있습니다. 플러그인에서, 내 토네이도 프로세스에서 사용하고있는 것과 동일한 tornado_mysql 라이브러리를 사용하고 싶습니다. 나는 토네이도의 run_sync() 방법으로이 작업을 수행 할 수 있었다 :비 토네이도 파이썬 스크립트에서 tornado_mysql을 어떻게 사용할 수 있습니까?

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

이것은 정확히 맞았습니다. 감사합니다! –