在Tornado中持久化运行时对象

1 投票
1 回答
1579 浏览
提问于 2025-04-17 02:02

我正在做一个基于Tornado的项目,这个项目非常依赖这个库的异步功能。通过参考聊天示例,我已经让我的应用程序实现了长轮询,但我似乎遇到了一些问题。

简单来说,我想做的是能够在UpdateManager类上调用一个函数,让它完成等待列表中所有回调的异步请求。下面是一些代码来解释我的意思:

update.py:

class UpdateManager(object):
  waiters = []
  attrs = []
  other_attrs = []

  def set_attr(self, attr):
    self.attrs.append(attr)

  def set_other_attr(self, attr):
    self.other_attrs.append(attr)

  def add_callback(self, cb):
    self.waiters.append(cb)

  def send(self):
    for cb in self.waiters:
      cb(self.attrs, self.other_attrs)

class LongPoll(tornado.web.RequestHandler, UpdateManager):
  @tornado.web.asynchronous 
  def get(self):
    self.add_callback(self.finish_request)

  def finish_request(self, attrs, other_attrs):
    # Render some JSON to give the client, etc...

class SetSomething(tornado.web.RequestHandler):
  def post(self):
    # Handle the stuff...
    self.add_attr(some_attr)

(还有更多代码实现了URL处理程序/服务器等,但我认为这些对这个问题来说不是必要的)

所以我想要的是能够从我应用程序的其他地方调用UpdateManager.send,并且仍然能够将数据发送给等待的客户端。问题是,当你尝试这样做时:

from update import UpdateManager
UpdateManager.send()

它只获取了UpdateManager类,而不是持有用户回调的那个实例。所以我的问题是:有没有办法在Tornado中创建一个持久对象,让我可以在整个应用程序中共享同一个UpdateManager的实例?

1 个回答

4

不要使用实例方法,应该使用类方法(毕竟,你已经在使用类属性,只是可能没有意识到而已)。这样,你就不需要创建对象,而是可以直接调用类本身的方法,这样就像是一个单例模式:

class UpdateManager(object):
  waiters = []
  attrs = []
  other_attrs = []

  @classmethod
  def set_attr(cls, attr):
    cls.attrs.append(attr)

  @classmethod
  def set_other_attr(cls, attr):
    cls.other_attrs.append(attr)

  @classmethod
  def add_callback(cls, cb):
    cls.waiters.append(cb)

  @classmethod
  def send(cls):
    for cb in cls.waiters:
      cb(cls.attrs, cls.other_attrs)

这样会让...

from update import UpdateManager
UpdateManager.send()

按你想要的方式工作。

撰写回答