В настоящее время я пытаюсь понять очередь задач движка Google (gae).
Как показать прогресс для выполнения задачи очереди задач приложения Google?
У меня есть проблема, которая очень похожа на this
Поэтому я закодированы небольшое приложение в соответствии с решением «Чачан».
Так что моя главная проблема - опросить значение прогресса с сайта html.
Я написал небольшую «очередь задач Hello gae», которая принимает число от пользователя и печатает это число, умноженное на все число от 1 до 10. Расчет выполняется по задаче. Источник является следующее:
#hellogaequeue.py
import os
import time
import webapp2
import jinja2
import logging
import json
from google.appengine.api import taskqueue
template_dir = os.path.join(os.path.dirname(__file__), 'templates')
JINJA_ENV = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir), autoescape = True)
myresults = [] # the results of the task in a list
myProgressValue = 0 # represents the progess of the task. range[ 0, 100 ]
#define the main handler to show the html-site and post some data to the task.
class MainHandler(webapp2.RequestHandler):
def get(self):
#gets the calculated results of the task (therefor empty at first call)
#and give it to the jinja2 framework to render the html page
template_values = {'myresults': myresults}
counter_template = JINJA_ENV.get_template('counter.html')
self.response.out.write(counter_template.render(template_values))
# if user clicks the button, we write the data from the input field onto 'key' and
# than add a new task, with the parameter holding the value of 'key'
def post(self):
key = self.request.get('key')
# Add the task to the default queue.
taskqueue.add(url='/worker', params={'key': key})
self.redirect('/') #calls MainHandler.get(...), which shows than 'counter.html' again
#define the handler for the task worker
class TaskWorker(webapp2.RequestHandler):
def post(self):
# ensure to use the global variables
global myresults
global myProgressValue
# get the 'params={'key': key}' value
key = self.request.get('key')
#now imagine this for loop takes 5 minutes to finish
#how to show the progress of this loop in 'counter.html'
for x in xrange(1, 11):
time.sleep(1)
res = x*int(key)
myresults.append(str(res))
myProgressValue = myProgressValue + 10
class ProgressWorker(webapp2.RequestHandler):
def get(self):
global myProgressValue
logging.info("Call to ProgressHandler. MyProgressValue is = {p}".format(p=myProgressValue))
json_result = json.dumps({ "progress" : myProgressValue })
self.response.headers['Content-Type'] = 'application/json; charset=UTF-8'
self.response.out.write(json_result)
application = webapp2.WSGIApplication([ ('/', MainHandler), ('/worker', TaskWorker), ('/progress', ProgressWorker) ], debug=True)
Источник 'counter.html' является:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello gae task queue with jQuery UI Progressbar</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
</head>
<body>
<form action="/" method="POST">
<input type="text" name="key" id="key">
<input type="submit" value="start gae task">
</form>
{% for counter in myresults %}
<li>
{{counter}}
</li>
{% endfor %}
<div id="progressbar"></div>
<div id="dbg"></div>
<script>
function refresh()
{
var progressVal = 0
$.ajax(
{
type: 'GET',
url: '/progress',
success: function(data)
{
var obj = JSON.parse(data);
progressVal = obj.progress;
document.getElementById("dbg").innerHTML = obj.progress;
},
error: function(xhr, status, error)
{
alert(xhr.status);
alert(error);
}
});
$("#progressbar").progressbar(
{
value: progressVal
});
}
$(function()
{
setInterval("refresh()", 3000);
});
</script>
</body>
</html>
Итак, первый вопрос:
Почему jquerys progressbar не работает? (Нет предупреждений.) Что я делаю неправильно?
Второй вопрос:
Это правильный способ сделать это?
Учитывая, что цикл for занимает больше времени, чем 60 секунд. Поэтому невозможно поместить его в функцию MainHandler.post (..), потому что это приведет к превышению допустимой конечной ошибки. И я должен также упомянуть, что for-loop не смог запустить Concurrent.
Дополнительно: Структура папок моего GAE проекта:
hellogaequeue
-templates
-counter.html
-app.yaml
-hellogaequeue.py
-queue.yaml
и app.yaml выглядит следующим образом:
application: queuetest-app-id
version: 1
runtime: python27
api_version: 1
threadsafe: true
libraries:
- name: jinja2
version: latest
handlers:
- url: /.*
script: hellogaequeue.application
MyProgressValue следует сохранить в базе данных gae. Поскольку Google запускает новые экземпляры приложения, поэтому все глобальные параметры сбрасываются до начального значения. В журнале GAE говорится: «Этот запрос вызвал новый процесс для вашего приложения, и, таким образом, вызвал загрузку вашего кода приложения в первый раз. Этот запрос может потребовать больше времени и использовать больше CPU, чем типичный запрос для ваше приложение." – user1911091