使用 Tornado 拥有持久的运行时对象

发布于 2024-12-04 09:36:07 字数 1454 浏览 2 评论 0原文

我正在 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 的单个实例?

I'm working on a project in Tornado that relies heavily on the asynchronous features of the library. By following the chat demo, I've managed to get long-polling working with my application, however I seem to have run into a problem with the way it all works.

Basically what I want to do is be able to call a function on the UpdateManager class and have it finish the asynchronous request for any callbacks in the waiting list. Here's some code to explain what I mean:

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)

(There's more code implementing the URL handlers/server and such, however I don't believe that's necessary for this question)

So what I want to do is make it so I can call UpdateManager.send from another place in my application and still have it send the data to the waiting clients. The problem is that when you try to do this:

from update import UpdateManager
UpdateManager.send()

it only gets the UpdateManager class, not the instance of it that is holding user callbacks. So my question is: is there any way to create a persistent object with Tornado that will allow me to share a single instance of UpdateManager throughout my application?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寂寞陪衬 2024-12-11 09:36:07

不要使用实例方法 - 使用 类方法 (毕竟,你是已经使用了类属性,您可能没有意识到)。这样,您不必实例化该对象,而可以只调用类本身的方法,该类本身充当单例:

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()

按照您的意愿工作。

Don't use instance methods - use class methods (after all, you're already using class attributes, you just might not realize it). That way, you don't have to instantiate the object, and can instead just call the methods of the class itself, which acts as a singleton:

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)

This will make...

from update import UpdateManager
UpdateManager.send()

work as you desire it to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文