2012-02-16 101 views
2

我的代碼如下所示:扭曲的非阻塞方法 - 如何?

... # class Site(Resource) 
def render_POST(self,request) 
    otherclass.doAssync(request.args) 
    print '1' 
    return "done" #that returns the HTTP response, always the same. 

... 

def doAssync(self,msg): 
    d = defer.Deferred() 
    reactor.callLater(0,self.doStuff,d,msg) 
    d.addCallback(self.sucess) 

def doStuff(self,d,msg): 
    # do some stuff 
    time.sleep(2) #just for example 
    d.callback('ok') 

def sucess(msg): 
    print msg 

輸出:

確定

到目前爲止,一切都很好,但是,HTTP響應(回報「完成'),只發生在延遲(time.sleep(2))之後。 我可以告訴你,因爲瀏覽器保持'加載'2秒。

我在做什麼錯?

+0

找到一些答案:http://stackoverflow.com/questions/6759115/asynchronous-wsgi-with-twisted – joaoricardo000 2012-02-16 11:45:45

+2

請注意您使用哪些線程Twisted API - 包括Deferreds,即d.callback - in。此版本的代碼在錯誤的線程中使用'd.callback'。這會導致所有的回調都在錯誤的線程中運行,只要您不僅僅打印結果,這些回調可能會破壞某些內容。 – 2012-02-16 17:12:57

回答

3

你做錯了什麼是運行阻塞呼叫(time.sleep(2)),而Twisted希望你只執行非阻塞操作。不等待的事情。因爲那裏有那個time.sleep(2),Twisted在該功能休眠時不能做任何事情。所以它也不能向瀏覽器發送任何數據。

time.sleep(2)的情況下,您可以用另一個reactor.callLater呼叫替換它。假設你實際上意味着time.sleep(2)調用是其他阻塞操作,如何解決它取決於操作。如果您可以以非阻塞的方式進行操作,請執行此操作。對於許多這樣的操作(如數據庫交互),Twisted已經有了非阻塞的替代方案。如果你正在做的事情沒有非阻塞接口,並且Twisted沒有替代它,你可能需要在單獨的線程中運行代碼(例如使用twisted.internet.threads.deferToThread),儘管這需要你的代碼實際上是線程-安全。

+0

那麼,他可以用'deferToThread(...)'代替'reactor.callLater(...)'嗎? – 2012-02-16 12:35:19

+0

是的,只是這樣做,解決了我的問題!謝謝!! – joaoricardo000 2012-02-16 13:19:20

+0

如果您執行reactor.callInThread(global_function)和global_function,則會執行阻止操作,如讀取本地文件並處理其內容。只要global_function正在運行,工廠線程似乎會受到影響,因爲響應顯着減慢,你知道爲什麼嗎? – 2015-08-28 18:35:48