为什么我的应用程序引擎任务会阻止页面刷新?
问题描述:
我正在学习App Engine任务队列。我的应用程序有处理文档的任务。每项任务大约需要5-10分钟才能完成。我的目标是通过网页监控每项任务的进度。为什么我的应用程序引擎任务会阻止页面刷新?
作为一项测试,我用一个简单的循环对push queue tutorial code进行了修改(见下文)。当提交“分析器页面”表单时,会启动一个新的“事务循环”任务。
我很惊讶异步的'事务循环'阻止了'分析器页'的刷新,直到任务完成。
我有两个问题:
-
为什么异步任务停止页面刷新?
我对任务背后的实现的幼稚看法是,每个任务都是一个预定的线程或进程,'transaction loop'线程会在数据存储io期间阻塞,让'分析器页面'线程刷新。 (这是不感兴趣的,因为我们的最终代码将与此测试显着不同)
使用数据存储/ 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)
答
开发应用程序服务器是单线程的,这就是为什么你刷新页面被阻塞,直到任务完成。
嗨斯图尔特,感谢您的答复。这就说得通了。虽然此功能使开发任务密集型应用程序变得非常棘手。你有什么建议如何开发这个?我当然可以在开发中模拟(存根?)任务,但如果有标准方法,那将会很好。你可以运行应用引擎虚拟机吗? – brif