#python #google-app-engine #cron #task-queue
#python #google-app-engine #cron #очередь задач
Вопрос:
У меня каждый день есть задание cron для выполнения вызова API и извлечения некоторых данных. Для каждой строки данных я запускаю очередь задач для обработки данных (что включает в себя поиск данных через дополнительные API). Как только все это закончится, мои данные не изменятся в течение следующих 24 часов, поэтому я кэширую их.
Есть ли способ узнать, когда завершатся все задачи, которые я поставил в очередь, чтобы я мог кэшировать данные?
В настоящее время я делаю это действительно беспорядочно, просто планируя два задания cron, подобные этому:
class fetchdata(webapp.RequestHandler):
def get(self):
todaykey = str(date.today())
memcache.delete(todaykey)
topsyurl = 'http://otter.topsy.com/search.json?q=site:open.spotify.com/albumamp;window=damp;perpage=20'
f = urllib.urlopen(topsyurl)
response = f.read()
f.close()
d = simplejson.loads(response)
albums = d['response']['list']
for album in albums:
taskqueue.add(url='/spotifyapi/', params={'url':album['url'], 'score':album['score']})
class flushcache(webapp.RequestHandler):
def get(self):
todaykey = str(date.today())
memcache.delete(todaykey)
Затем мой cron.yaml выглядит следующим образом:
- description: gettopsy
url: /fetchdata/
schedule: every day 01:00
timezone: Europe/London
- description: flushcache
url: /flushcache/
schedule: every day 01:05
timezone: Europe/London
В принципе — я предполагаю, что выполнение всех моих задач не займет более 5 минут, поэтому я просто очищаю кэш через 5 минут, и это гарантирует, что при кэшировании данных он будет завершен.
Есть ли лучший способ кодирования этого? Похоже, мое решение не самое лучшее….
Спасибо, Том
Ответ №1:
В настоящее время нет никакого способа определить, когда ваши задачи завершили выполнение. Лучшим вариантом было бы вставить записи маркеров в хранилище данных и заставить каждую задачу удалять свою запись, когда это будет сделано. Затем каждая задача может проверить, является ли она последней, и выполнить очистку / кэширование, если это так.
Комментарии:
1. спасибо, ник — приятно знать, что я не пропустил ничего очевидного. Я попробую то, что вы предлагаете
Ответ №2:
я нашел этот вопрос, когда занимался той же проблемой. я придумал другое решение, которое публикую здесь на случай, если оно пригодится другим.
это не прямая замена тому, что вы просите, но это связано — моя проблема заключалась в том, что я хотел знать, когда очередь была пуста, потому что это означает, что сложный фоновый процесс завершил выполнение. таким образом, я мог бы заменить проверку размера очереди проверкой «таймера мертвеца»
время ожидания — это таймер, который постоянно сбрасывается каким-либо процессом. когда этот процесс завершается, таймер не сбрасывается и в конечном итоге истекает. итак, у меня были все различные задачи, которые составляли часть моего сложного фонового процесса, сбросили таймер, и вместо проверки, когда очередь была пуста, у меня было задание cron, которое проверяло, когда истек таймер.
конечно, чтобы это было эффективно, таймер должен избегать постоянной записи в хранилище данных. код в http://acooke.org/cute/Deadmantim0.html позволяет избежать этого, слегка смягчая поведение и используя memcache для хранения копии объекта timer и сброса его в хранилище только по истечении значительного промежутка времени.
ps это более эффективно, чем то, что вы описываете, потому что для этого не нужно так часто записывать данные в базу данных. это также более надежно, потому что вам не нужно точно отслеживать, что происходит.
Комментарии:
1. И это также менее надежно, поскольку счетчик может истечь из-за того, что все выполняемые задачи выполняются слишком медленно. Я думаю, на практике это может быть достаточно маловероятно.