From 597e6c66d54af0596cfe218073a9a5002dea4213 Mon Sep 17 00:00:00 2001 From: John Eskew Date: Tue, 22 May 2018 15:28:11 -0400 Subject: [PATCH] Add backoff module as a new requirement. Use backoff when calling Sailthru API to retry upon optout timeouts. --- lms/djangoapps/email_marketing/signals.py | 17 +++++++++++++++++ requirements/edx/base.in | 1 + requirements/edx/base.txt | 1 + requirements/edx/development.txt | 1 + requirements/edx/testing.txt | 1 + 5 files changed, 21 insertions(+) diff --git a/lms/djangoapps/email_marketing/signals.py b/lms/djangoapps/email_marketing/signals.py index 13cecaf21b..90a6d6561b 100644 --- a/lms/djangoapps/email_marketing/signals.py +++ b/lms/djangoapps/email_marketing/signals.py @@ -5,6 +5,7 @@ import datetime import logging from random import randint +import backoff import crum from celery.exceptions import TimeoutError from django.conf import settings @@ -263,7 +264,23 @@ def _log_sailthru_api_call_time(time_before_call): delta_sailthru_api_call_time.microseconds / 1000) +def _backoff_handler(details): + """ + Simple logging handler for when timeout backoff occurs. + """ + log.info('Trying again in {wait:0.1f} seconds after {tries} tries calling {target}'.format(**details)) + + +def _not_a_timeout(e): + return 'timed out' not in e.message + + @receiver(USER_RETIRE_MAILINGS) +@backoff.on_exception(backoff.expo, + Exception, + max_time=600, # Only 10 minutes of trying + giveup=_not_a_timeout, # Stop trying if exception is *not* a timeout. + on_backoff=_backoff_handler) def force_unsubscribe_all(sender, **kwargs): # pylint: disable=unused-argument """ Synchronously(!) unsubscribes the given user from all Sailthru email lists. diff --git a/requirements/edx/base.in b/requirements/edx/base.in index 27ed86bf2d..1512ec0b13 100644 --- a/requirements/edx/base.in +++ b/requirements/edx/base.in @@ -26,6 +26,7 @@ analytics-python==1.1.0 # Used for Segment analytics attrs # Reduces boilerplate code involving class attributes Babel==1.3 # Internationalization utilities, used for date formatting in a few places +backoff bleach==1.4 # Allowed-list-based HTML sanitizing library that escapes or strips markup and attributes; used for capa and LTI boto==2.39.0 # Deprecated version of the AWS SDK; we should stop using this boto3==1.4.8 # Amazon Web Services SDK for Python diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index a41ad6d631..556965fbee 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -51,6 +51,7 @@ argparse==1.4.0 asn1crypto==0.24.0 attrs==17.4.0 babel==1.3 +backoff==1.5.0 beautifulsoup==3.2.1 # via pynliner billiard==3.3.0.23 # via celery bleach==1.4 diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index b82870b7e1..7c831e0a32 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -57,6 +57,7 @@ asn1crypto==0.24.0 astroid==1.5.2 attrs==17.4.0 babel==1.3 +backoff==1.5.0 backports.functools-lru-cache==1.5 beautifulsoup4==4.6.0 beautifulsoup==3.2.1 diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 065b637032..5a35a8878e 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -54,6 +54,7 @@ asn1crypto==0.24.0 astroid==1.5.2 # via edx-lint, pylint, pylint-celery, pylint-plugin-utils attrs==17.4.0 babel==1.3 +backoff==1.5.0 backports.functools-lru-cache==1.5 # via astroid, pylint beautifulsoup4==4.6.0 beautifulsoup==3.2.1