带阻塞功能的Twisted LoopingCall

2024-05-13 19:22:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个应用程序,它需要轮询数据库中可能的配置更改。该应用程序是一个使用Twisted的简单xmlrpc服务器。我尝试过使用Twisted的LoopingCall来执行轮询,但是由于LoopingCall运行在主线程上,对db的调用是阻塞的。因此,如果db调用由于某种原因而很慢,那么对xmlrpc服务器的请求必须等待。所以我试着在一个线程中运行LoopingCall,但没能真正让它工作。我的问题是,我应该把它运行在线程中吗?如果是,怎么办?在

from twisted.web import xmlrpc, server
from twisted.internet.threads import deferToThread
from twisted.internet import reactor, task
import platform
from time import sleep

r = reactor

class Agent(xmlrpc.XMLRPC):
    self.routine()
    xmlrpc.XMLRPC.__init__(self)

    def xmlrpc_echo(self, x):
        """
        Return arg as a simple test that the server is running
        """
        return x

    def register(self):
        """
        Register Agent with db and pick up config
        """
        sleep(3)  # simulate slow db call
        print 'registered with db'

    def routine(self):
        looping_register = task.LoopingCall(self.register)
        looping_register.start(7.0, True)

if __name__ == '__main__':
    r.listenTCP(7081, server.Site(Agent()))
    print 'Agent is running on "%s"' % platform.node()
    r.run()

Tags: fromimportself服务器register应用程序dbserver
1条回答
网友
1楼 · 发布于 2024-05-13 19:22:51

你应该用扭曲的.enterprise.adbapi模块。通过在线程池中运行所有与DBAPI 2.0兼容的客户机并返回延迟到您的标准,它将为您提供非阻塞api:

from twisted.enterprise import adbapi


dbpool = adbapi.ConnectionPool('psycopg2', 'mydb', 'andrew', 'password') # replace psycopg2 with your db client name.

def getAge(user):
    return dbpool.runQuery('SELECT age FROM users WHERE name = ?', user)

def printResult(l):
    if l:
        print l[0][0], "years old"
    else:
        print "No such user"

getAge("joe").addCallback(printResult)

有关更多信息和示例,请访问官方文档:https://twistedmatrix.com/documents/14.0.0/core/howto/rdbms.html

相关问题 更多 >