代码之家  ›  专栏  ›  技术社区  ›  Peter Farmer

此任务队列设置有什么问题?

  •  0
  • Peter Farmer  · 技术社区  · 14 年前

    我已经在为客户托管的站点上设置了此任务队列实现,它具有 cron job 每天早上2点开始 /admin/tasks/queue ,这会将要发送的电子邮件排队, /admin/tasks/email “和使用 cursors 以便小批量排队。因为某种原因昨晚 /管理/任务/队列 一直用这个代码运行,所以发送了我所有的电子邮件配额 :/ . 我对这个代码做了什么错误吗?

    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")
    
    1 回复  |  直到 14 年前
        1
  •  2
  •   Wooble    14 年前

    我可以看到一些潜在的问题。首先,您将光标存储在memcache中,这并不能保证任何内容的持久性。如果在处理过程中出现缓存丢失,将再次发送每条消息。

    第二,如果任务因任何原因失败,它们将被重新尝试;因为这个原因,它们应该被设计成等幂的。当然,在发送电子邮件的情况下,这几乎是不可能的,因为一旦发送了一条消息,如果您的任务在发送后由于其他原因而死亡,它就不能回滚。至少,我建议在发送消息后,尝试更新每个订阅实体上的“上次电子邮件发送日期”字段。当然,这本身并不是万无一失的,因为电子邮件发送可能会成功,之后实体的更新可能会失败。它还将增加整个过程的开销,因为您将为每个订阅服务器进行写操作。