Tornado Chatdemo与Coroutines合作

时间:2014-06-19 17:17:31

标签: python asynchronous web tornado coroutine

我正在努力制作协同版龙卷风聊天演示,我无法理解它。由于我是新的协程式编程,我真的很讨厌回调,因为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

1 个答案:

答案 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))