当使用redis消息订阅的异步任务之后,tornado 主程序无法启动
使用CacheQueue3才能解决问题,具体原因后面再细看源码,
CacheQueue1
import redis
import logging
class CacheQueue(object):
def __init__(self, host, port, cache_update_path):
self._pool_cache = redis.ConnectionPool(host=host, port=port, db=0)
@gen.coroutine
def listen():
r = redis.StrictRedis(connection_pool=self._pool_cache)
p = r.pubsub()
p.subscribe("cache_update_path")
for item in p.listen():
if item['type'] == 'message':
logging.info(item['data'])
CacheQueue2
import redis
import logging
from threading import Thread
class CacheQueue(object):
def __init__(self, host, port, cache_update_path):
self._pool_cache = redis.ConnectionPool(host=host, port=port, db=0)
def async_listen():
thead_sub = Thread(target=self.listen, args=(byte,))
thead_sub.start()
def listen():
r = redis.StrictRedis(connection_pool=self._pool_cache)
p = r.pubsub()
p.subscribe("cache_update_path")
for item in p.listen():
if item['type'] == 'message':
logging.info(item['data'])
CacheQueue3
import redis
import logging
from concurrent import futures
executor = futures.ThreadPoolExecutor(max_workers=1)
class CacheQueue(object):
def __init__(self, host, port, cache_update_path):
self._pool_cache = redis.ConnectionPool(host=host, port=port, db=10)
self.cache_update_path =cache_update_path
def _listen(self,pool_cache):
logging.info('async ==> redis_cache')
r = redis.StrictRedis(connection_pool=pool_cache)
p = r.pubsub()
p.subscribe("cache_update_path")
for item in p.listen():
logging.info('get publish content')
print item
if item['type'] == 'message':
logging.info(item['data'])
self.cache_update_path.add(item['data'])
def async_listen(self):
executor.submit(self._listen, self._pool_cache)
调用代码片段
class Application(tornado.web.Application):
def __init__(self, settings=None, script=None):
self.cache_queue = CacheQueue(host=self.settings.get('redis_host', 'localhost'),
port=self.settings.get('redis_port', 6379),
cache_update_path=self.cache_update_path)
tornado.web.Application.__init__(self, handlers, **self.settings)
#问题点: 当使用redis消息订阅的异步任务之后,tornado 主程序无法启动
#self.cache_queue.listen() #使用对象CacheQueue 1 : 失败
#使用对象CacheQueue 2 : 也是失败
#使用对象CacheQueue 3 : 启动成功
self.cache_queue.async_listen()
def main():
... 参数解析
app = Application(settings=settings, script=script)
app.port = port
http_server = tornado.httpserver.HTTPServer(app, xheaders=True)
http_server.listen(options.port)
....
tornado.ioloop.IOLoop.instance().start()