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

问题描述:

我正在学习App Engine任务队列。我的应用程序有处理文档的任务。每项任务大约需要5-10分钟才能完成。我的目标是通过网页监控每项任务的进度。为什么我的应用程序引擎任务会阻止页面刷新?

作为一项测试,我用一个简单的循环对push queue tutorial code进行了修改(见下文)。当提交“分析器页面”表单时,会启动一个新的“事务循环”任务。

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

我有两个问题:

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

    我对任务背后的实现的幼稚看法是,每个任务都是一个预定的线程或进程,'transaction loop'线程会在数据存储io期间阻塞,让'分析器页面'线程刷新。 (这是不感兴趣的,因为我们的最终代码将与此测试显着不同)

  2. 使用数据存储/ memcache来记录任务进度似乎相当重,特别是在写配额方面 - 有没有更好的方法去做这个?

感谢,

布赖恩


测试开发服务器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) 

开发应用程序服务器是单线程的,这就是为什么你刷新页面被阻塞,直到任务完成。

+0

嗨斯图尔特,感谢您的答复。这就说得通了。虽然此功能使开发任务密集型应用程序变得非常棘手。你有什么建议如何开发这个?我当然可以在开发中模拟(存根?)任务,但如果有标准方法,那将会很好。你可以运行应用引擎虚拟机吗? – brif