簡體   English   中英

Tornado異步調用函數

[英]Tornado async call to a function

我正在使用Python + Tornado創建一個Web應用程序,它基本上為用戶提供文件。 我沒有數據庫。

如果文件可用,則直接拾取和提供文件,如果沒有,則立即生成。

我希望以異步方式提供客戶端,因為某些文件可能已經可用,而其他文件需要生成(因此需要等待,我不希望它們阻止其他用戶)。

我有一個管理文件選擇或生成的類,我只需要從Tornado調用它。

實現這一目標的最佳方法(在CPU和RAM上最有效)是什么? 我應該使用線程嗎? 一個子流程? 一個簡單的gen.Task喜歡這個嗎?

另外,我希望我的實現能夠在Google App Engines上運行(我認為它們不允許生成子流程?)。

我對異步Web服務比較新,所以歡迎任何幫助。

我找到了我的問題的答案:genTask示例確實是實現異步調用的最佳方式,這是因為該示例確實使用了Python協程 ,乍一看我並不理解,因為我認為yield只用於返回生成器的值。

具體例子:

class MyHandler(tornado.web.RequestHandler):

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

這里重要的是兩件事的結合:

  • yield ,實際上產生了一個協程(或偽線程,這是非常有效的,並且是高度並發友好的)。 http://www.python.org/dev/peps/pep-0342/

  • gen.Task()是一個非阻塞(異步)函數,因為如果你在一個阻塞函數上產生一個協程,它就不會是異步的。 gen.Task()由Tornado提供,專門用於處理Python的協程語法。 更多信息: http//www.tornadoweb.org/documentation/gen.html

因此,使用協同程序在Python中進行異步調用的規范示例:

response = yield non_blocking_func(**kwargs)

現在文檔有解決方案。

簡單的例子:

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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM