我每天都有一个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分钟之后刷新缓存,这样可以确保数据缓存时它已经完成。
有更好的编码方法吗?感觉像我的解决方案不是最好的....
由于 汤姆
答案 0 :(得分:6)
目前还没有任何方法可以确定您的任务何时完成执行。您最好的选择是在数据存储区中插入标记记录,并让每个任务在完成后删除其记录。然后,每个任务都可以检查它是否是最后一个任务,如果是,则执行清理/缓存。
答案 1 :(得分:2)
我在处理同样的问题时发现了这个问题。我提出了一个不同的解决方案,我在这里发布,以防其他人有用。
这不是你要求的直接替代,但它是相关的 - 我的问题是我想知道队列何时为空,因为这意味着复杂的后台进程已经完成运行。所以我可以用“deadman timer”来替换检查队列大小
死人时间是一个由某个进程不断重置的计时器。当该过程结束时,计时器不会重置并最终到期。所以我拥有构成我的复杂后台进程一部分的所有不同任务重置计时器,而不是检查队列何时为空,我有一个cron作业,检查计时器何时到期。
当然,为了提高效率,定时器必须始终避免写入数据存储。 http://acooke.org/cute/Deadmantim0.html处的代码通过稍微放松行为并使用memcache来保存计时器对象的副本并且仅在经过大量时间后才在存储中重置它来避免这种情况。
ps这比你描述的更有效,因为它不需要经常写入数据库。它也更加强大,因为您无需准确跟踪发生的情况。