我嘗試使用txredis(非阻塞扭曲API for redis)爲持久消息隊列嘗試設置與我正在工作的scrapy項目。我發現雖然客戶端沒有被阻塞,但是它變得比原來慢得多,因爲反應器迴路中應該發生的一件事情被分成幾千個步驟。Twisted:爲什麼將延遲迴調傳遞給延遲線程會讓線程突然間阻塞?
因此,我嘗試使用redis-py(常規阻塞扭曲API)並將調用封裝在延遲線程中。它工作的很好,但是當我打電話給redis時,我想執行一個內部延遲,因爲我想設置連接池以嘗試進一步提高速度。
下面是我從扭曲的文檔採取延期線程一些示例代碼解釋,說明我的使用情況:
#!/usr/bin/env python
from twisted.internet import reactor,threads
from twisted.internet.task import LoopingCall
import time
def main_loop():
print 'doing stuff in main loop.. do not block me!'
def aBlockingRedisCall():
print 'doing lookup... this may take a while'
time.sleep(10)
return 'results from redis'
def result(res):
print res
def main():
lc = LoopingCall(main_loop)
lc.start(2)
d = threads.deferToThread(aBlockingRedisCall)
d.addCallback(result)
reactor.run()
if __name__=='__main__':
main()
這裏是我改變了連接池,使代碼遞延線程阻止:
#!/usr/bin/env python
from twisted.internet import reactor,defer
from twisted.internet.task import LoopingCall
import time
def main_loop():
print 'doing stuff in main loop.. do not block me!'
def aBlockingRedisCall(x):
if x<5: #all connections are busy, try later
print '%s is less than 5, get a redis client later' % x
x+=1
d = defer.Deferred()
d.addCallback(aBlockingRedisCall)
reactor.callLater(1.0,d.callback,x)
return d
else:
print 'got a redis client; doing lookup.. this may take a while'
time.sleep(10) # this is now blocking.. any ideas?
d = defer.Deferred()
d.addCallback(gotFinalResult)
d.callback(x)
return d
def gotFinalResult(x):
return 'final result is %s' % x
def result(res):
print res
def aBlockingMethod():
print 'going to sleep...'
time.sleep(10)
print 'woke up'
def main():
lc = LoopingCall(main_loop)
lc.start(2)
d = defer.Deferred()
d.addCallback(aBlockingRedisCall)
d.addCallback(result)
reactor.callInThread(d.callback, 1)
reactor.run()
if __name__=='__main__':
main()
所以我的問題是,沒有人知道爲什麼我的改變導致的遞延線程會阻止和/或任何人都可以提出一個更好的解決方案?
真棒的感謝! – surtyaar 2010-03-18 00:36:33