2014-11-06 53 views
1

我有一個應用程序需要輪詢數據庫以查找可能的配置更改。該應用程序是一個使用Twisted的簡單xmlrpc服務器。我嘗試過使用Twisted的LoopingCall來執行輪詢,但因爲LoopingCall在主線程上運行,所以對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() 
+1

你不應該除非你看到他們被記錄爲支持這個,否則在另一個線程中運行任何Twisted API。幾乎沒有Twisted API支持這一點 - 如果您嘗試以這種方式使用它們,它們會以一些隨機難以調試的方式破解。 – 2014-11-08 13:29:20

+0

是的,我正在學習這種困難的方式。感謝您的好建議 – MFB 2014-11-09 23:04:06

回答

1

您應該使用twisted.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

+0

或者更好,adbapi2模塊,twextpy的一部分 - https://pypi.python.org/pypi/twextpy/0.1a12469 – 2014-11-08 13:28:34

+0

twextpy.enterprise.adbapi2看起來不錯,但我沒有工作它 – 2014-11-09 09:43:12

+0

嗯謝謝我從這些文檔學到了很多,技術上你的答案是正確的,所以我相應地標記了它。但是,在我的情況下,數據庫是非關係的(MongoDB)。我沒有提到它,因爲我沒有意識到它是相關的。 – MFB 2014-11-09 23:03:43