我正在使用Tornado Web服务器来排队需要在请求/响应周期之外处理的项目。
在下面的简化示例中,每次请求进入时,我都会向名为queued_items
的列表中添加一个新字符串。我想创建一些能够观察该列表并处理其中显示的项目的内容。
(在我的实际代码中,这些项目是通过TCP套接字处理和发送的,当Web请求到达时,可能会或可能不会连接。我希望Web服务器不管套接字连接如何都能保持排队等等)
我正在尝试保持此代码简单,而不是使用Redis或Beanstalk等外部队列/程序。它不会有很高的音量。
使用Tornado成语来查看新项目的client.queued_items
列表并在它们到达时处理它们有什么好方法?
import time
import tornado.ioloop
import tornado.gen
import tornado.web
class Client():
def __init__(self):
self.queued_items = []
@tornado.gen.coroutine
def watch_queue(self):
# I have no idea what I'm doing
items = yield client.queued_items
# go_do_some_thing_with_items(items)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
client.queued_items.append("%f" % time.time())
self.write("Queued a new item")
if __name__ == "__main__":
client = Client()
# Watch the queue for when new items show up
client.watch_queue()
# Create the web server
application = tornado.web.Application([
(r'/', IndexHandler),
], debug=True)
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
答案 0 :(得分:11)
有一个名为toro
的库,它为tornado
提供同步原语。 [更新:截至龙卷风4.2,toro
已合并到tornado
。]
听起来你可以使用toro.Queue
(或tornado.queues.Queue
4.2+中的tornado
来处理这个问题:
import time
import toro
import tornado.ioloop
import tornado.gen
import tornado.web
class Client():
def __init__(self):
self.queued_items = toro.Queue()
@tornado.gen.coroutine
def watch_queue(self):
while True:
items = yield self.queued_items.get()
# go_do_something_with_items(items)
class IndexHandler(tornado.web.RequestHandler):
@tornado.gen.coroutine
def get(self):
yield client.queued_items.put("%f" % time.time())
self.write("Queued a new item")
if __name__ == "__main__":
client = Client()
# Watch the queue for when new items show up
tornado.ioloop.IOLoop.instance().add_callback(client.watch_queue)
# Create the web server
application = tornado.web.Application([
(r'/', IndexHandler),
], debug=True)
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
除了将数据结构从列表切换到toro.Queue
之外,还需要进行一些调整:
watch_queue
安排add_callback
在IOLoop内部运行,而不是直接在IOLoop上下文之外调用它。IndexHandler.get
需要转换为协程,因为toro.Queue.put
是协程。 我还在while True
添加了watch_queue
循环,以便它永远运行,而不是只处理一个项目然后退出。