我在我为客户托管的网站上设置了此任务队列实施,它有一个cron job
,每天早上凌晨2点运行“/admin/tasks/queue
”,这会将要发送的电子邮件排队,“/admin/tasks/email
”,并使用cursors
以便以小块进行排队。出于某种原因昨晚/admin/tasks/queue
继续使用此代码运行,因此发送了我的整个电子邮件配额:/
。我这个代码做错了吗?
class QueueUpEmail(webapp.RequestHandler):
def post(self):
subscribers = Subscriber.all()
subscribers.filter("verified =", True)
last_cursor = memcache.get('daily_email_cursor')
if last_cursor:
subscribers.with_cursor(last_cursor)
subs = subscribers.fetch(10)
logging.debug("POST - subs count = %i" % len(subs))
if len(subs) < 10:
logging.debug("POST - Less than 10 subscribers in subs")
# Subscribers left is less than 10, don't reschedule the task
for sub in subs:
task = taskqueue.Task(url='/admin/tasks/email', params={'email': sub.emailaddress, 'day': sub.day_no})
task.add("email")
memcache.delete('daily_email_cursor')
else:
logging.debug("POST - Greater than 10 subscibers left in subs - reschedule")
# Subscribers is 10 or greater, reschedule
for sub in subs:
task = taskqueue.Task(url='/admin/tasks/email', params={'email': sub.emailaddress, 'day': sub.day_no})
task.add("email")
cursor = subscribers.cursor()
memcache.set('daily_email_cursor', cursor)
task = taskqueue.Task(url="/admin/tasks/queue", params={})
task.add("queueup")
答案 0 :(得分:2)
我可以看到几个潜在的问题。首先,将光标存储在memcache中,不保证可以保留任何内容。如果您在处理过程中获得缓存未命中,则会再次重新发送每封邮件。
其次,如果因任何原因失败,任务将被重新审判;因为这个原因,它们应该被设计成幂等的。当然,在发送电子邮件的情况下,这几乎是不可能的,因为一旦发送了消息,如果您的任务在发送后因某些其他原因而死亡,则无法回滚。至少,我建议在发送消息后尝试更新每个Subscriber实体上的“上次发送电子邮件的日期”字段。当然,这本身并不是万无一失的,因为电子邮件发送可能会成功,之后实体的更新可能会失败。它还会增加整个过程的开销,因为你要为每个订阅者写一个。