【发布时间】:2014-06-19 17:17:30
【问题描述】:
我正在尝试制作 tornado 聊天演示的协程版本,但我无法理解它。因为我是协程编程风格的新手,我真的很讨厌自 javascript 以来的回调。
我想将 MessageUpdateHandler 更改为真正使用协程。
class MessageBuffer(object):
def __init__(self):
self.waiters = set()
self.cache = []
self.cache_size = 200
def wait_for_messages(self, callback, cursor=None):
if cursor:
new_count = 0
for msg in reversed(self.cache):
if msg["id"] == cursor:
break
new_count += 1
if new_count:
callback(self.cache[-new_count:])
return
self.waiters.add(callback)
def cancel_wait(self, callback):
self.waiters.remove(callback)
def new_messages(self, messages):
logging.info("Sending new message to %r listeners", len(self.waiters))
for callback in self.waiters:
try:
callback(messages)
except:
logging.error("Error in waiter callback", exc_info=True)
self.waiters = set()
self.cache.extend(messages)
if len(self.cache) > self.cache_size:
self.cache = self.cache[-self.cache_size:]
# Making this a non-singleton is left as an exercise for the reader.
global_message_buffer = MessageBuffer()
class MessageUpdatesHandler(BaseHandler):
@tornado.web.authenticated
@tornado.web.asynchronous
def post(self):
cursor = self.get_argument("cursor", None)
global_message_buffer.wait_for_messages(self.on_new_messages,
cursor=cursor)
def on_new_messages(self, messages):
# Closed client connection
if self.request.connection.stream.closed():
return
self.finish(dict(messages=messages))
def on_connection_close(self):
global_message_buffer.cancel_wait(self.on_new_messages)
我尝试删除 @tornado.web.asynchronous 并替换为 @tornado.gen.coroutine 但这就是我所能做到的,我不明白如何在没有 on_new_messages(self, messages) 回调的情况下产生 global_message_buffer.wait_for_messages(),据我所知,它会使回调过时。
global_message_buffer 设计有回调,但是,yields 没有回调,那么如何让它们产生呢?
tornado 聊天示例演示:https://github.com/tornadoweb/tornado/blob/c9af9a7224b1f42e91ad88b0a3f8f10478584b0a/demos/chat/chatdemo.py#L101
【问题讨论】:
标签: python asynchronous web tornado coroutine