我正在学习 App Engine 任务队列。我的应用程序具有处理文档的任务。每个任务大约需要 5-10 分钟才能完成。我的目标是通过网页监控每项任务的进度。
作为测试,我用一个简单的循环调整了推送队列教程代码(见下文)。当提交“分析器页面”表单时,将启动一个新的“事务循环”任务。
我很惊讶异步“事务循环”阻止了“分析器页面”的刷新,直到任务完成。
我有两个问题:
为什么异步任务会停止页面刷新?
我对任务背后的实现的幼稚看法是,每个任务都是一个计划线程或进程,并且“事务循环”线程会在数据存储 io 期间阻塞,让“分析器页面”线程刷新。(这是出于兴趣,因为我们的最终代码将与此测试有很大不同)
使用数据存储/内存缓存来记录任务进度似乎相当重,尤其是在写入配额方面——有没有更好的方法来做到这一点?
谢谢,
布赖恩
在开发服务器 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)