报告Google Appengine上长请求的进度

时间:2013-10-06 19:39:30

标签: java google-app-engine

我正在努力实现一个Web应用程序,将Google Appengine作为后端,其预期行为如下:

  1. 用户为复杂分析选择几个参数
  2. 用户按“开始”
  3. 最初为空的“响应”页面返回给用户,但处理继续
  4. 分析以某种方式在服务器上继续,并且正在计算部分结果,它们会在响应页面中显示/添加。
  5. 我预计总计算量大约为30-40秒(因此在Appengine要求的60秒内)。

    步骤1和2是微不足道的。我知道第4步可以使用步骤AJAX完成,但我不确定我究竟能如何实现第3步。

    谢谢!

2 个答案:

答案 0 :(得分:3)

您可以使用任务队列和数据存储区。你需要3个处理程序:

  1. 任务处理程序,做了很多努力。它会将其进度存储在数据存储区中。
  2. 在后台启动任务并返回“空白”页面的处理程序
  3. 获取状态的处理程序
  4. 注意:页面不能为空。它必须有javascript来检查状态。我认为Channel API也是如此。

    无论如何是Python中的代码:

    class LongTaskStatus(ndb.Model):
      is_complete = ndb.BooleanProperty()
      percentage = ndb.FloatProperty()
      messages = ndb.StringProperty(repeated=True)
    
    class LongTaskHandler(webapp2.RequestHandler):
      def get(self):
    
        # Query for existing status model or create a new one
    
        # Does work ...
    
        # Update progress
        status = LongTaskStatus()
        status.messages.appen('Still busy...')
        status.put()
    
        # Does work ...
    
    class StartHandler(webapp2.RequestHandler):
      def get(self):
    
        # start the task
        taskqueue.add(url='/longtask')
    
        # Return a page which uses javascript to check the progress every few seconds
        template = JINJA_ENVIRONMENT.get_template('taskprogress.html')
        self.response.write(template.render(template_values))
    
    class CheckTaskStatus(wenapp2.RequestHandler):
      def get(self):
        query = LongTaskStatus.query().fetch(1)
        result = {}
        if query:
          status = query[0]
          result = {
            'is_complete': status.is_complete,
            'percentage': status.percentage,
            'messages': status.messages
          }
        self.response.write(json.dumps(result))
    

    并且是“空白”页面:

    <!DOCTYPE html>
    <html lang="en">
      <body>
        <div id="status"></div>
        <script>
          window.setInterval(function(){
            $.get( "ajax/test.html", function( data ) {
              $( ".status" ).html( data );
            });
          }, 5000);
        </script>
      </body>
    </html>
    

    编辑:没有任务队列的其他选项

    如果您有一种独特的方法来识别任务,那么您可以通过不使用任务队列API来加快此方法的速度。

    以下是:

    1. 通过javascript
    2. 调用LongTaskHandler
    3. 重定向到加载页面,该页面调用CheckTaskStatus。
    4. 这应该比使用任务队列更快,但遗憾的是,您需要一种在启动任务之前识别任务的方法。例如用户ID,会话等

答案 1 :(得分:1)

查看Channel API。它允许您将消息从服​​务器推送到客户端。