我正在尝试使用基于Tornado的NATS来使用client来使用异步函数来接收和发送消息。一旦收到消息,就必须调用一个阻塞函数,我试图在一个单独的线程上实现,以允许接收和发布消息,将消息放入Tornado队列,以便以后处理阻塞函数。
我对Tornado(以及python多线程)非常陌生,但在多次阅读Tornado文档和其他资源后,我已经能够提供代码的工作版本,如下所示: / p>
import tornado.gen
import tornado.ioloop
from tornado.queues import Queue
from concurrent.futures import ThreadPoolExecutor
from nats.io.client import Client as NATS
messageQueue = Queue()
nc = NATS()
@tornado.gen.coroutine
def consumer():
def processMessage(currentMessage):
# process the message ...
while True:
currentMessage = yield messageQueue.get()
try:
# execute the call in a separate thread to prevent blocking the queue
EXECUTOR.submit(processMessage, currentMessage)
finally:
messageQueue.task_done()
@tornado.gen.coroutine
def producer():
@tornado.gen.coroutine
def enqueueMessage(currentMessage):
yield messageQueue.put(currentMessage)
yield nc.subscribe("new_event", "", enqueueMessage)
@tornado.gen.coroutine
def main():
tornado.ioloop.IOLoop.current().spawn_callback(consumer)
yield producer()
if __name__ == '__main__':
main()
tornado.ioloop.IOLoop.current().start()
我的问题是:
1)这是使用Tornado调用阻塞函数的正确方法吗?
2)实施始终聆听的消费者/生产者计划的最佳做法是什么?我担心我的while True:
声明实际上阻止了处理器......
3)我如何检查队列以确保一连串的呼叫被排队?我尝试过使用Queue()。qSize(),但它总是返回零,这让我想知道排队是否正确完成。
答案 0 :(得分:1)
一般规则(NYKevin的信用)是:
IO的ThreadPoolExecutor,CPU的ProcessPoolExecutor。两者都有内部队列,两者都扩展为最多指定的max_workers
。有关concurrent executors in docs的更多信息。
答案是:
while True
如果您有例如有些人产生了异步调用(偶数yield gen.sleep(0.01)
),它将控制权交还给ioloop qsize()
是调用的权利,但由于我没有运行/调试这个并且我会采用不同的方法(现有池),因此很难在这里找到问题。