Запустить функцию, когда очередь задач пуста на appengine

Каждый день у меня есть работа 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/album&window=d&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 минут, и это гарантирует, что когда данные будут кэшированы, они будут завершены.

Есть ли лучший способ закодировать это? Такое чувство, что мое решение не самое лучшее....

Спасибо, Том.


person tomcritchlow    schedule 05.04.2011    source источник


Ответы (2)


В настоящее время нет никакого способа определить, когда ваши задачи закончили выполнение. Лучшим вариантом было бы вставить записи маркеров в хранилище данных, чтобы каждая задача удаляла свою запись по завершении. Затем каждая задача может проверить, является ли она последней задачей, и выполнить очистку/кэширование, если это так.

person Nick Johnson    schedule 05.04.2011
comment
спасибо Ник - приятно знать, что я не пропустил что-то очевидное. Я попробую то, что вы предлагаете - person tomcritchlow; 05.04.2011

Я нашел этот вопрос, решая ту же проблему. Я придумал другое решение, которое публикую здесь на случай, если оно будет полезно другим.

это не прямая замена того, что вы спрашиваете, но это связано - моя проблема заключалась в том, что я хотел знать, когда очередь была пустой, потому что это означает, что сложный фоновый процесс завершился. поэтому я мог бы заменить проверку размера очереди проверкой «таймера мертвеца»

Время мертвеца — это таймер, который постоянно сбрасывается каким-то процессом. когда этот процесс завершается, таймер не сбрасывается и в конечном итоге истекает. поэтому у меня были все различные задачи, которые составляли часть моего сложного фонового процесса, сбрасывали таймер, и вместо того, чтобы проверять, когда очередь была пустой, у меня было задание cron, которое проверяло, когда истекал таймер.

конечно, чтобы это было эффективно, таймер должен постоянно избегать записи в хранилище данных. код на http://acooke.org/cute/Deadmantim0.html позволяет избежать этого, ослабляя незначительное поведение и использование memcache для хранения копии объекта таймера и сброса его в хранилище только после того, как прошло значительное количество времени.

ps это более эффективно, чем то, что вы описываете, потому что ему не нужно так часто записывать в базу данных. это также более надежно, потому что вам не нужно точно отслеживать, что происходит.

person andrew cooke    schedule 03.08.2011
comment
И это также менее надежно, так как счетчик может истечь из-за того, что все запущенные задачи выполняются слишком медленно. На практике это может быть достаточно маловероятным, я думаю. - person maaartinus; 19.07.2013