2016-03-09 3 views
1

Мы используем Google App Engine и встроенные TaskQueues для отправки ежедневных обновлений электронной почты с использованием Mandrill. Они отправляются в определенное время, и их, как правило, много. Мы планируем одну задачу для каждого отправленного письма, а некоторые из них терпят неудачу, потому что API-интерфейс Mandrill истекает или мы нажимаем некоторый предел скорости.Задача повтора в очереди, не вызывая ошибки при мониторинге

Наш код выглядит следующим образом:

@app.route('/worker/send_transactional_email/', methods=['POST']) 
def worker_send_transactional_mail(): 

    payload = json.loads(request.values.get('payload')) 

    message = { 
     'to': [payload.get('to')], 
     'subject': payload.get('subject'), 
     'from_name': 'Our App', 
     'from_email': "[email protected]", 
     'text': payload.get('body_text') 
    } 

    mandrill_payload = _get_mandrill_payload(message) 

    url = "https://mandrillapp.com/api/1.0/messages/send-template.json" 
    req = urllib2.Request(url, mandrill_payload, {'Content-Type': 'application/json'}) 
    try: 
     urllib2.urlopen(req) 
    except urllib2.URLError as error: 
     logging.info("to: " + unicode(payload.get('to'))) 
     logging.info("subject: " + unicode(payload.get('subject'))) 
     logging.info(error.code) 
     logging.info(error.read()) 
     abort(500) 
    return 'ok' 

решение работает довольно хорошо, как задачи, которые терпят неудачу повторит позже и обычно завершается тогда. Единственная проблема, с которой мы сталкиваемся, заключается в том, что сбои в работе журнала ошибок появляются в журнале ошибок и приводят к тому, что Google Cloud Monitoring сообщает об ошибках.

Я хочу заменить abort(500) в блоке except выше с чем-то, что говорит TaskQueue, чтобы повторить задачу, но не регистрировать какую-либо ошибку или что-то в этом роде. Я знаю, что могу вернуть любой код статуса, отличный от 200-299, и TaskQueue будет повторять попытку, но я не уверен, что правильный путь - вернуть 301 или что-то, потому что это очень вводит в заблуждение.

+0

Вместо того, чтобы прерывать, отправьте новое задание с помощью API очереди задач и просто верните 200. –

+0

Я никогда об этом не рассказывал. Единственная проблема с этим подходом заключается в том, что это невозможно сделать на одном атомном шаге, верно? Это означает, что между добавлением в очередь задач и отправкой назад 200 может произойти сбой, и задача будет удвоена в задаче! – Sgoettschkes

ответ

0

Если вы настроили повторы в очереди, ничего не нужно менять в вашем коде, так как ответ 500 позволит логике очереди знать, чтобы вызвать повтор. Не нужно вручную перезаписывать вручную, если вы не достигнете максимальных повторных попыток, и в этом случае у вас должны быть другие средства обеспечения того, чтобы вы могли либо окончательно отслеживать требуемое завершение задачи, либо повторно задерживать или просто перехватывать последнюю попытку, проверяя заголовок X-Appengine-Taskretrycount. Как упоминалось в документах, make sure tasks are idempotent.

+0

Да, у нас нет никаких проблем с повторениями. Проблема заключается в том, что ошибка регистрируется, и мониторинг ее подбирает. Это добавляет значительный шум, который я бы хотел удалить. – Sgoettschkes

+0

Хм, очень интересно. У вас есть 3 варианта, как я вижу: ** 1) ** отделить обработчик задачи от своего собственного модуля, чтобы изолировать от любых других 500, ** 2) ** вернуть другой код (с различными ограничениями), ** 3) * * сделать запрос функции в [Public Issue Tracker для облачной платформы] (https://code.google.com/p/google-cloud-platform/issues/list), причем запрошенная функция является более сложной фильтрацией на графиках ответов кода состояния от модуля GAE, позволяющего фильтровать по маршруту, а также регистрировать данные в запросе. – Nick

+1

На самом деле, я бы предпочел иметь 4) Имейте определенное сообщение об ошибке функции/ошибки/ответа, которое запускает повторную попытку без всех сбоев. Подобно 'taskqueue.retry()', который прерывает текущий запрос без сбоев (возврат 200), но вызывает повторную попытку. – Sgoettschkes