我用producer& amp;修改了示例队列来自此Tornado https://github.com/spring-projects/spring-integration-java-dsl/issues/59的消费者,但似乎传递给get()的超时参数根本不起作用,因为消费者在抛出异常之前不等待10秒。理想情况下,生产者和消费者将同时运行。另外,我不知道是否以秒或毫秒传递timeout参数:
from tornado import gen
from tornado.ioloop import IOLoop
from tornado.queues import Queue
q = Queue()
@gen.coroutine
def consumer():
try:
while True:
item = yield q.get(timeout=10000)
try:
print('Doing work on %s' % item)
finally:
q.task_done()
except gen.TimeoutError:
print('timeout')
return
@gen.coroutine
def producer():
for item in range(5):
yield q.put(item)
print('Put %s' % item)
yield gen.sleep(2)
@gen.coroutine
def main():
# Start consumer without waiting (since it never finishes).
IOLoop.current().spawn_callback(consumer)
yield producer() # Wait for producer to put all tasks.
yield q.join() # Wait for consumer to finish all tasks.
print('Done')
IOLoop.current().run_sync(main)
这是执行:
Put 0
Doing work on 0
timeout
Put 1
Put 2
Put 3
Put 4
答案 0 :(得分:4)
超时
您可以阅读Tornado' Queue.get docs:
返回一个可在项目可用时解析的Future,或者在超时后引发tornado.gen.TimeoutError。
但这可能会产生误导,因为timeout
实际上是deadline
。因此必须使用datetime.timedelta object:
import datetime
yield q.get(timeout=datetime.timedelta(seconds=1))
或绝对时间:
timeout = 1.5 # in seconds, floats acceptable
deadline = IOLoop.current().time() + timeout
# in most cases IOLoop time is just time.time()
# I've used separate variables only for the notion
yield q.get(timeout=deadline)
在Toro中,已合并到Tornado中,此参数称为deadline
。
在您的代码中,您指定了超时10000
,这意味着Thu, 01 Jan 1970 02:46:40 GMT
的截止日期。
消费者循环
由于您对整个功能try
/ except
进行了阻止,包括while
循环,当TimeoutError
发生时,您的消费者就会停止工作。将异常处理移至while
循环。
工作示例:
from tornado import gen
from tornado.ioloop import IOLoop
from tornado.queues import Queue
q = Queue()
@gen.coroutine
def consumer():
i = 0
while True:
i += 1
print('get cycle %s' % i)
try:
item = yield q.get(IOLoop.instance().time() + 3)
try:
print('Doing work on %s' % item)
finally:
q.task_done()
except gen.TimeoutError:
print('timeout')
@gen.coroutine
def producer():
for item in range(5):
yield q.put(item)
print('Put %s' % item)
yield gen.sleep(2)
@gen.coroutine
def main():
# Start consumer without waiting (since it never finishes).
IOLoop.current().spawn_callback(consumer)
yield producer() # Wait for producer to put all tasks.
yield q.join() # Wait for consumer to finish all tasks.
print('Done')