0

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

作为测试,我用一个简单的循环调整了推送队列教程代码(见下文)。当提交“分析器页面”表单时,将启动一个新的“事务循环”任务。

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

我有两个问题:

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

    我对任务背后的实现的幼稚看法是,每个任务都是一个计划线程或进程,并且“事务循环”线程会在数据存储 io 期间阻塞,让“分析器页面”线程刷新。(这是出于兴趣,因为我们的最终代码将与此测试有很大不同)

  2. 使用数据存储/内存缓存来记录任务进度似乎相当重,尤其是在写入配额方面——有没有更好的方法来做到这一点?

谢谢,

布赖恩


在开发服务器 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)
4

1 回答 1

2

开发应用程序服务器是单线程的,这就是为什么您的刷新页面在任务完成之前被阻止的原因。

于 2012-06-20T22:46:52.330 回答