我正在努力制作协同版龙卷风聊天演示,我无法理解它。由于我是新的协程式编程,我真的很讨厌回调,因为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
,但就我而言,我不明白如何在没有global_message_buffer.wait_for_messages()
回调的情况下产生on_new_messages(self, messages)
据我所知,它使得回调过时了。
global_message_buffer设计有一个回调但是,yeilds没有回调,那么如何产生它们呢?
龙卷风聊天exmaple演示:https://github.com/tornadoweb/tornado/blob/c9af9a7224b1f42e91ad88b0a3f8f10478584b0a/demos/chat/chatdemo.py#L101
答案 0 :(得分:1)
这是一个简单的例子,希望它有所帮助:
class MessageUpdatesHandler(BaseHandler):
@tornado.web.authenticated
@gen.coroutine
def post(self):
cursor = self.get_argument("cursor", None)
messages = yield gen.Task(global_message_buffer.wait_for_messages, cursor=cursor)
if self.request.connection.stream.closed():
return
self.finish(dict(messages=messages))