Skip to content

Commit 3917337

Browse files
refactor: simplify SES routing and fallback logic per review feedback
1 parent 83ef742 commit 3917337

3 files changed

Lines changed: 25 additions & 89 deletions

File tree

common/djangoapps/student/views/management.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@
8989
from common.djangoapps.util.json_request import JsonResponse
9090
from common.djangoapps.student.signals import USER_EMAIL_CHANGED
9191
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
92-
from openedx.core.djangoapps.ace_common.utils import apply_ses_routing_if_enabled
9392

9493
log = logging.getLogger("edx.student")
9594

@@ -231,7 +230,6 @@ def compose_activation_email(
231230
user_context=message_context,
232231
)
233232

234-
msg = apply_ses_routing_if_enabled(msg)
235233
return msg
236234

237235

openedx/core/djangoapps/ace_common/utils.py

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,10 @@
22
Utility functions for edx-ace.
33
"""
44
import logging
5-
from django.conf import settings
6-
from edx_toggles.toggles import WaffleFlag
7-
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
85

96

107
log = logging.getLogger(__name__)
118

12-
# .. toggle_name: user_authn.enable_ses_for_account_activation
13-
# .. toggle_implementation: WaffleFlag
14-
# .. toggle_default: False
15-
# .. toggle_description: Route account activation emails via SES using ACE.
16-
# .. toggle_use_cases: opt_in, temporary
17-
# .. toggle_creation_date: 2026-03-31
18-
# .. toggle_target_removal_date: None
19-
# .. toggle_warning: Controls SES routing for account activation emails.
20-
21-
ENABLE_SES_FOR_ACCOUNT_ACTIVATION = WaffleFlag(
22-
'user_authn.enable_ses_for_account_activation',
23-
__name__,
24-
)
25-
26-
27-
def apply_ses_routing_if_enabled(msg):
28-
"""
29-
Apply SES routing to ACE message if flag is enabled.
30-
"""
31-
if not ENABLE_SES_FOR_ACCOUNT_ACTIVATION.is_enabled():
32-
return msg
33-
34-
if msg.options is None:
35-
msg.options = {}
36-
37-
msg.options.update({
38-
'transactional': True,
39-
'override_default_channel': 'django_email',
40-
'from_address': configuration_helpers.get_value(
41-
'ACTIVATION_EMAIL_FROM_ADDRESS'
42-
) or configuration_helpers.get_value(
43-
'email_from_address',
44-
settings.DEFAULT_FROM_EMAIL
45-
),
46-
})
47-
48-
return msg
49-
509

5110
def setup_firebase_app(firebase_credentials, app_name='fcm-app'):
5211
"""

openedx/core/djangoapps/user_authn/tasks.py

Lines changed: 25 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,24 @@
1818
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
1919
from openedx.core.djangoapps.user_authn.utils import check_pwned_password
2020
from openedx.core.lib.celery.task_utils import emulate_http_request
21-
from openedx.core.djangoapps.ace_common.utils import ENABLE_SES_FOR_ACCOUNT_ACTIVATION
21+
from edx_toggles.toggles import WaffleFlag
2222

2323
log = logging.getLogger('edx.celery.task')
2424

25+
# .. toggle_name: user_authn.enable_ses_for_account_activation
26+
# .. toggle_implementation: WaffleFlag
27+
# .. toggle_default: False
28+
# .. toggle_description: Route account activation emails via SES using ACE.
29+
# .. toggle_use_cases: opt_in, temporary
30+
# .. toggle_creation_date: 2026-03-31
31+
# .. toggle_target_removal_date: None
32+
# .. toggle_warning: Controls SES routing for account activation emails.
33+
34+
ENABLE_SES_FOR_ACCOUNT_ACTIVATION = WaffleFlag(
35+
'user_authn.enable_ses_for_account_activation',
36+
__name__,
37+
)
38+
2539

2640
@shared_task
2741
@set_code_owner_attribute
@@ -79,59 +93,28 @@ def send_activation_email(self, msg_string, from_address=None, site_id=None):
7993
sent_via_ses = False
8094

8195
if route_via_ses:
82-
msg.options.update({
83-
'override_default_channel': 'django_email',
84-
'transactional': True,
85-
'from_address': configuration_helpers.get_value(
86-
'ACTIVATION_EMAIL_FROM_ADDRESS'
87-
) or configuration_helpers.get_value(
88-
'email_from_address',
89-
settings.DEFAULT_FROM_EMAIL
90-
),
91-
})
96+
msg.options['override_default_channel'] = 'django_email'
9297

9398
try:
9499
with emulate_http_request(site=site, user=user):
95100
ace.send(msg)
96101
sent_via_ses = route_via_ses
97102

98103
except RecoverableChannelDeliveryError:
99-
log.warning(
100-
"SES send failed for %s, falling back to default ACE channel",
101-
dest_addr,
102-
exc_info=True,
103-
)
104-
105-
if not route_via_ses:
106-
log.info(
107-
'Retrying sending email to user {dest_addr}, attempt # {attempt} of {max_attempts}'.format(
108-
dest_addr=dest_addr,
109-
attempt=retries,
110-
max_attempts=max_retries
111-
)
104+
if route_via_ses:
105+
log.warning(
106+
"SES send failed for %s, falling back to default ACE channel",
107+
dest_addr,
108+
exc_info=True,
112109
)
113-
try:
114-
self.retry(
115-
countdown=settings.RETRY_ACTIVATION_EMAIL_TIMEOUT,
116-
max_retries=max_retries
117-
)
118-
except MaxRetriesExceededError:
119-
log.error(
120-
'Unable to send activation email to user from "%s" to "%s"',
121-
from_address,
122-
dest_addr,
123-
exc_info=True
124-
)
125-
return
126110

127-
_remove_ses_overrides(msg)
111+
msg.options.pop('override_default_channel', None)
128112

129-
try:
130113
with emulate_http_request(site=site, user=user):
131114
ace.send(msg)
132115
sent_via_ses = False
133116

134-
except RecoverableChannelDeliveryError:
117+
else:
135118
log.info(
136119
'Retrying sending email to user {dest_addr}, attempt # {attempt} of {max_attempts}'.format(
137120
dest_addr=dest_addr,
@@ -151,6 +134,8 @@ def send_activation_email(self, msg_string, from_address=None, site_id=None):
151134
dest_addr,
152135
exc_info=True
153136
)
137+
return
138+
154139
except Exception:
155140
log.exception(
156141
'Unable to send activation email to user from "%s" to "%s"',
@@ -164,9 +149,3 @@ def send_activation_email(self, msg_string, from_address=None, site_id=None):
164149
dest_addr,
165150
'SES' if sent_via_ses else 'default ACE channel',
166151
)
167-
168-
169-
def _remove_ses_overrides(msg):
170-
msg.options.pop('override_default_channel', None)
171-
msg.options.pop('transactional', None)
172-
msg.options.pop('from_address', None)

0 commit comments

Comments
 (0)