如何在Twisted中延迟Django数据库操作?

6 投票
3 回答
1521 浏览
提问于 2025-04-15 15:29

我有一个正常运行的Django网站。此外,还有一个Twisted进程,它监听Jabber的在线状态通知,并使用Django的ORM更新Django数据库。

到目前为止,这个过程是可行的,因为我只是调用相应的Django模型(在正确设置好环境后)。不过,这样会阻塞Twisted应用程序,这不是我想要的效果。

由于我对Twisted还不太熟悉,所以不太清楚如何以非阻塞的方式使用deferreds来访问Django数据库(通过它的ORM)。

  1. deferredGenerator?
  2. twisted.enterprise.adbapi?(绕过ORM?)
  3. ???

当解析到在线状态消息时,我想在Django数据库中保存用户的jid_str是在线还是离线(使用Django模型UserProfile)。我用这个函数来实现:

def django_useravailable(jid_str, user_available):
    try:
        userhost = jid.JID(jid_str).userhost()
        user = UserProfile.objects.get(im_jabber_name=userhost)
        user.im_jabber_online = user_available
        user.save()
        return jid_str, user_available
    except Exception, e:
        print e
    raise jid_str, user_available,e

目前,我是这样调用它的:

d = threads.deferToThread(django_useravailable, from_attr, user_available)
d.addCallback(self.success)
d.addErrback(self.failure)

3 个回答

0

我有一个正在运行的Twisted应用程序,里面用到了Django的数据库操作工具(ORM)。我并没有延迟处理它。我知道这样做是不对的,但到目前为止还没有遇到什么问题。

1

我用你说的那种方法成功了。你可以看看文档,里面提到 twisted 的数据库接口其实是用线程来处理的,因为大多数 SQL 库都是阻塞式的。

我有一个 twisted 服务器,它用来保存现场的电力监测数据。这个服务器会不时启动一个子线程,然后调用我的 Django 保存代码。你可以在这个博客链接上了解更多关于我实时数据收集的内容。

你是在说你启动了一个子线程,但它还是会阻塞吗?

1

“我有一个正常运行的Django网站。”

这个网站可能是在Apache服务器上运行的,使用了mod_wsgi或者类似的东西。

如果你是在Apache里用mod_wsgi的嵌入模式,要注意Apache是多线程的,你的Python线程会和Apache的线程混在一起。这种情况下,分析哪些东西在阻塞可能会变得很麻烦。

如果你是在守护进程模式下使用mod_wsgi(其实你应该这样做),那么你的Django就会是一个独立的进程。

为什么不继续这个设计思路,把你的“jabber监听器”也做成一个独立的进程呢?

如果你希望这个进程可以在多个服务器上运行,可以通过init.rccron来启动它。

因为它是一个独立的进程,所以不会争抢资源。你的Django进程运行得很快,而你的Jabber监听器则可以独立运行。

撰写回答