2011-04-05 73 views
5

我每天都有一个cron作业来调用API并获取一些数据。对于每行数据,我启动一个任务队列来处理数据(包括通过其他API查找数据)。一旦所有这些都完成了,我的数据在接下来的24小时内不会改变,所以我memcache它。当appengine上的任务队列为空时运行函数

有没有办法知道我排队的所有任务何时完成,以便可以缓存数据?

目前我做一个真正的时尚凌乱通过只安排2个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分钟后刷新缓存,这确保了数据缓存完成。

有没有更好的编码方式?感觉就像我的解决方案是不是最好的....

感谢 汤姆

回答

6

有当前没有任何的方法来确定当你的任务已经执行完毕。您最好的选择是在数据存储中插入标记记录,并在完成后让每个任务删除记录。然后每个任务都可以检查它是否是最后一项任务,并且如果是的话就执行清理/缓存。

+0

谢谢尼克 - 很高兴知道我没有错过任何明显的事情。我会尝试你的建议 – tomcritchlow 2011-04-05 03:36:32

2

我在处理同一问题时发现此问题。我想出了一个不同的解决方案,我在这里发布信息以防其他人使用。

这不是直接取代你所问的,而是相关的 - 我的问题是我想知道队列是空的,因为这意味着一个复杂的后台进程已经完成运行。所以我可以通过检查“deadman timer”来替换检查队列大小

deadman time是一个计时器,它不断地被某个进程重置。当该过程完成时,定时器不会重置并最终到期。所以我有所有不同的任务,形成我的复杂后台进程的一部分重置计时器,而不是检查队列是否为空时,我有一个计时器过期时检查的cron作业。

当然,为了高效,定时器必须避免一直写入数据存储区。 http://acooke.org/cute/Deadmantim0.html的代码通过略微放宽行为并使用memcache来保存计时器对象的副本并在经过大量时间后才将其重置在存储中来避免此问题。

ps这比你描述的更有效率,因为它不需要经常写入数据库。它也更强大,因为您不必精确追踪发生的情况。

+0

它也不太健壮,因为计数器可能会因所有运行任务太慢而失效。实际上,这可能不太可能,我想。 – maaartinus 2013-07-19 13:38:54

相关问题