2

在 GAE 上,我需要对 PiCloud 服务器进行一些 REST 调用,然后根据 PiCloud 返回值创建一个输出页面。但是,PiCloud 需要几分钟来处理模型。因此我想知道是否可以先创建一个“加载”页面,然后在完成计算后,呈现真正的输出页面。

具体来说,问题是我如何不断检查我的 REST 服务的状态,然后生成不同的 HTML 页面。

我感谢任何建议和意见!

PS:jQuery BlockUI 似乎是一个很好的例子,但它需要估计超时持续时间,我猜不到......

调用 REST 服务的函数:

def get_jid(pdf_t, pdf_nop, pdf_p):
    response = urlfetch.fetch(url=url, payload=data, method=urlfetch.POST, headers=http_headers) 
    jid= json.loads(response.content)['jid']
    output_st = "running"
        
    while output_st!="done":
        response_st = urlfetch.fetch(url='https://api.picloud.com/job/?jids=%s&field=status' %jid, headers=http_headers)
        output_st = json.loads(response_st.content)['info']['%s' %jid]['status']

    url_val = 'https://api.picloud.com/job/result/?jid='+str(jid)
    response_val = urlfetch.fetch(url=url_val, method=urlfetch.GET, headers=http_headers)
    output_val = json.loads(response_val.content)['result']
    return(jid, output_st, output_val)

生成 HTML 页面:

class pdfPage_loading(webapp.RequestHandler):
    def post(self):                              
        final_res=get_jid(pdf_t, pdf_nop, pdf_p)[2]
        html = html + template.render(templatepath + 'popup_pdf_eco.html', {
            'title':'Ubertool',
            'model_page':'',
            'model_attributes':'Please wait','text_paragraph':''})
        self.response.out.write(html)


class pdfPage_done(webapp.RequestHandler):
    def post(self):                              
        final_res=get_jid(pdf_t, pdf_nop, pdf_p)[2]
        html = html + template.render(templatepath + 'popup_pdf_eco.html', {
            'title':'Ubertool',
            'model_page':final_res,
            'model_attributes':'Please download your PDF here','text_paragraph':''})
        self.response.out.write(html)

app_loading = webapp.WSGIApplication([('/.*', pdfPage_loading)], debug=True)
app_done = webapp.WSGIApplication([('/.*', pdfPage_done)], debug=True)

def main():
    ##Here is the problematic part:
    if get_jid(pdf_t, pdf_nop, pdf_p)!='done':
        run_wsgi_app(app_pre)
    else:
        run_wsgi_app(app)

if __name__ == '__main__':
    main()  
4

1 回答 1

0

首先,您不需要多个 WSGIApplication 处理程序。您可以基于 URL 和 GET/POST 参数的请求。

我会混合使用任务和 Channel API:

当用户访问页面时:

  1. 创建一个频道令牌供用户使用
  2. 进行 REST API 调用
  3. 启动一个任务(如下所述),将创建的令牌和 PiCloud 作业的 id 传递给它
  4. 显示“加载页面”并让用户使用在步骤 1 中创建的令牌连接到 Channel API

在任务中,让它检查 PiCloud 作业的状态。如果状态未完成,让任务设置一个新任务以再次调用自己,并检查作业的状态。作业完成后,通过 Channel API 将数据传递给用户,以便他们可以加载页面内容或重定向到将为他们准备好内容的页面。

示例状态检查代码(这是使用来自 PiCloud 的示例代码,您可以使用自己的请求来获取状态urlfetch- 这仅作为示例,因此您可以根据需要插入代码以工作):

import cloud
from google.appengine.api import taskqueue
from google.appengine.api import channel

#<Your other hanlders here>

class CheckStatus(webapp.RequestHandler):
  def post(self):
    job_id = self.request.get('job_id')
    token = self.request.get('token')
    status = cloud.get('status')
    if status != 'done':
       taskqueue.add(url='/checkstatus', params={'job_id': job_id, 'token': token}, method="POST", countdown=3)
       return
    channel.send_message(token, '<some message here>')

app = webapp.WSGIApplication([('/done', pdfPage_done),
                              ('/checkstatus', CheckStatus),
                              ('/.*', pdfPage_loading)], debug=True)

def main():
  run_wsgi_app(app)

if __name__ == '__main__':
   main()  
于 2013-04-10T14:29:17.703 回答