2010-05-31 3 views
0

J'ai installé cette tâche la mise en œuvre de file d'attente sur un site je serai l'hôte pour un client, il a une cron job qui se déroule chaque matin à 2h du matin « /admin/tasks/queue », ce files d'attente des e-mails à être envoyés, « /admin/tasks/email », et utilise cursors donc pour faire la queue en petits morceaux. Pour une raison quelconque la nuit dernière /admin/tasks/queue continué à être exécuté par ce code et donc envoyé tout mon quota de courriels :/. Ai-je fait quelque chose de mal avec ce code?Quel est le problème avec cette configuration de la file d'attente des tâches?

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") 

Répondre

2

Je peux voir quelques problèmes potentiels. Tout d'abord, vous stockez votre curseur dans memcache, ce qui n'est pas garanti pour conserver quoi que ce soit. Si vous manquez une mémoire cache à mi-parcours, vous réexpéderez chaque message.

Deuxièmement, les tâches seront réessayées si elles échouent pour une raison quelconque; ils sont censés être conçus pour être idempotent pour cette raison. Dans le cas de l'envoi de courriels, bien sûr, c'est presque impossible, puisqu'une fois qu'un message est envoyé, il ne peut pas être annulé si votre tâche meurt pour une autre raison après l'avoir envoyée. Au minimum, je recommanderais d'essayer de mettre à jour un champ "date du dernier courriel" sur chaque entité d'abonné après leur avoir envoyé le message. Cela en soi n'est pas infaillible, bien sûr, puisque l'envoi d'email pourrait réussir et la mise à jour de l'entité pourrait échouer après cela. Cela ajouterait également des frais généraux à l'ensemble du processus, puisque vous seriez en train d'écrire pour chaque abonné.

+0

Merci pour votre analyse, ma pensée initiale était memcache pourrait être un problème. –

+0

Memcache était probablement la cause immédiate derrière le problème que vous aviez, oui. Votre meilleure approche serait de passer le curseur comme un argument de chaque tâche à l'autre. –

Questions connexes