2012-11-08 56 views
5

我正在使用基本上爲用戶提供文件的Python + Tornado製作一個Web應用程序。我沒有數據庫。龍捲風對功能的異步調用

如果文件可用,則直接提取並投放文件;如果不可用,則會立即生成文件。

我想客戶端以異步的方式服務,因爲一些文件可能已經可用,而其他文件需要生成(因此他們需要等待,我不希望他們阻止其他用戶)。

我有一個類來管理文件的拾取或生成,我只需要從Tornado中調用它。

什麼是最好的方式(最有效的CPU和RAM)來實現這一目標?我應該使用線程嗎?子過程?簡單的gen.Task like this one

另外,我希望我的實現可以在Google App Engines上工作(我認爲他們不允許子進程被產生?)。

我對異步web服務比較陌生,所以任何幫助都是值得歡迎的。

+1

的gen.Task將正常工作。如果你的文件獲取/生成代碼不能很好地播放,那麼一個線程將正常工作。您也可以產生多個進程,但我不知道Google App Engine的限制。 – sean

+0

感謝您的回覆。你也知道如果我產生多個gen.Task它將如何工作?我的意思是,如果這個方法被多個用戶多次調用,我的**實例方法**可能相當耗時且耗時,會發生什麼?所有方法是否將並行運行異步,或者下一個方法是否會先等待先前的方法終止? (請注意,我的整個應用程序中都使用了我的類的單個實例) – gaborous

+1

完全消隱後,應該沒問題,但無論您的解決方案如何,它都會成爲大量線程的問題。如果這是一個擔心,試着分解成分離的進程或在負載平衡後運行多個實例。 – sean

回答

10

我發現了我的問題的答案:genTask示例確實是實現異步調用的最佳方式,這是由於該示例確實使用了一個Python協程,乍看起來很明白,因爲我認爲收益率僅用於返回發電機的值。

具體的例子:

class MyHandler(tornado.web.RequestHandler): 

    @asynchronous 
    @gen.engine 
    def get(self): 
     response = yield gen.Task(self.dosomething, 'argument') 

什麼是這裏重要的是兩件事情的組合:

因此,在使用協同程序在Python中的異步調用的一個典型的例子:

response = yield non_blocking_func(**kwargs) 
+1

另外這裏是另一篇文章,其中詳細的協程和舊的回調實現: http://stackoverflow.com/questions/8812715/using-a-simple-python-generator-as-a-co-routine-in -a-龍捲風異步處理程序?RQ = 1 – gaborous

1

現在Documentation有解決方案。

簡單的例子:

import os.path 
import tornado.web 
from tornado import gen 

class MyHandler(tornado.web.RequestHandler): 

    @gen.coroutine 
    def get(self, filename): 
     result = yield self.some_usefull_process(filename) 
     self.write(result) 

    @gen.coroutine 
    def some_usefull_process(self, filename): 
     if not os.path.exists(filename): 
      status = yield self.generate_file(filename) 
      result = 'File created' 
     else: 
      result = 'File exists' 

     raise gen.Return(result) 

    @gen.coroutine 
    def generate_file(self, filename): 
     fd = open(filename, 'w') 
     fd.write('created') 
     fd.close()