2013-10-09 30 views
1

我試圖在線程內部放慢計算,並收到一個錯誤「request.finish被調用後請求調用request.write」。扭曲的錯誤:在request.finish被調用後請求調用了Request.write

我已經查看了答案,並找到完全相同的問題,但解決方案不適合我。請指教。

from twisted.web.server import Site, NOT_DONE_YET 
from twisted.web.resource import Resource 
from twisted.internet import reactor, threads 
from twisted.python import log 

import sys 
import time 


def SlowComputation(): 
    time.sleep(10) 
    return "Lang Computation Result" 


def FastComputation(): 
    return "Fast Computation Result" 


class PerformComputation(Resource): 
    def Success(self, request): 
     request.write('Success') 
     request.finish() 

    def Failure(self, request): 
     request.write('Failure') 
     request.finish() 

    def render_GET(self, request): 
     if 'fast' in request.args: 
      d = threads.deferToThread(FastComputation) 
      d.addCallback(self.Success(request)) 
      return NOT_DONE_YET 
     if 'slow' in request.args: 
      d = threads.deferToThread(SlowComputation) 
      d.addCallback(self.Success(request)) 
      return NOT_DONE_YET 


log.startLogging(sys.stdout) 
root = Resource() 
root.putChild("calculate", PerformComputation()) 
factory = Site(root) 
reactor.listenTCP(8880, factory, interface='localhost') 
reactor.run() 

回答

3

此:

d.addCallback(self.Success(request)) 

是一樣的:

temp = self.Success(request) 
d.addCallback(temp) 

其中,鑑於Success的定義是一樣的:

request.write('Success') 
request.finish() 
temp = None 
d.addCallback(None) 

這可能失敗與Request.write在調用Request.finish之後調用請求。,因爲d.addCallback(None)會引發異常,並且服務器嘗試將錯誤報告爲響應。但是,由於finish已被調用,因此無法寫入錯誤。

使用額外參數將回調添加到Deferred的正確方法是d.addCallback(self.Success, request)。在Deferred總是獲取回調通過Deferred的結果作爲第一個參數,雖然 - 所以Success正確的簽名是:

def Success(self, result, request): 
    ... 
+1

感謝讓 - 保羅,你的投入是非常寶貴的。另外,我在代碼中發現了我的拼寫錯誤。 –