为什么我的应用引擎任务会阻止页面刷新?

时间:2012-06-20 17:20:12

标签: python google-app-engine asynchronous transactions

我正在了解App Engine任务队列。我的应用程序具有处理文档的任务。每项任务大约需要5-10分钟才能完成。我的目标是通过网页监控每项任务的进度。

作为测试,我使用简单的循环调整了push queue tutorial code(见下文)。当提交“分析器页面”表单时,将启动新的“事务循环”任务。

我很惊讶异步“事务循环”阻止了“分析器页面”的刷新,直到任务完成。

我有两个问题:

  1. 为什么异步任务会停止页面刷新?

    我对任务背后的实现的天真看法是每个任务都是一个预定的线程或进程,并且“事务循环”线程将在数据存储期间阻塞,让“分析器页面”线程刷新。 (这是不感兴趣的,因为我们的最终代码将与此测试明显不同)

  2. 使用数据存储区/内存缓存来记录任务进度似乎相当重,特别是关于写入配额 - 有更好的方法吗?

  3. 谢谢,

    布赖恩


    在开发服务器1.6上测试:

    from google.appengine.api import taskqueue
    from google.appengine.ext import db
    from google.appengine.ext import webapp
    
    class Counter(db.Model):
         count = db.IntegerProperty(indexed=False)
    
    class Analyser(webapp.RequestHandler):
        # Analyser Page  -- Page refresh (get) only completes after task is called
        def get(self):
    
            self.response.write("<html> <body>")
    
            # My first  guess was that calling counter.put() blocked the Counter.all() 
            # call to the datastore. 
            # However commenting the following code had the same effect.
    
            # self.response.write("Counters:<br>")
            # counters = Counter.all()
            # for counter in counters:
            #   self.response.write(str(counter.count) + "<br>")
    
            self.response.write("<form action=\"/api/analyse\" method=\"post\"> \
                                Key: <input type=\"text\" name=\"key\" /><br /> \
                                <input type=\"submit\" value=\"Submit\" />  \
                            </form>")
    
            self.response.write("</body> </html>")
    
    def post(self):
        key = self.request.get('key')
        # Add the task to the default queue.
        taskqueue.add(url='/analyse_worker', params={'key': key})
        self.response.write("Added task with key:" + key)
    
    class AnalyserWorker(webapp.RequestHandler):
        def post(self): # should run at most 1/s
            key = self.request.get('key')
    
        def txn():
            counter = Counter.get_by_key_name(key)
            if counter is None:
                counter = Counter(key_name=key, count=1)
            else:
                counter.count += 1
            counter.put()
    
        # Transaction loop
        for i in range(0,200):
            db.run_in_transaction(txn)
    

1 个答案:

答案 0 :(得分:2)

dev appserver是单线程的,这就是在任务完成之前阻止刷新页面的原因。