Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
notifier
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
notifier
Commits
08eb44e6
Commit
08eb44e6
authored
Nov 05, 2014
by
jsa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
generate_and_send_digests should retry on comments service error
parent
22e48bd7
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
48 additions
and
35 deletions
+48
-35
notifier/tasks.py
+27
-33
notifier/tests/test_tasks.py
+21
-2
No files found.
notifier/tasks.py
View file @
08eb44e6
...
@@ -12,7 +12,7 @@ from django.core.mail import EmailMultiAlternatives
...
@@ -12,7 +12,7 @@ from django.core.mail import EmailMultiAlternatives
from
notifier.connection_wrapper
import
get_connection
from
notifier.connection_wrapper
import
get_connection
from
notifier.digest
import
render_digest
from
notifier.digest
import
render_digest
from
notifier.pull
import
generate_digest_content
from
notifier.pull
import
generate_digest_content
,
CommentsServiceException
from
notifier.user
import
get_digest_subscribers
,
UserServiceException
from
notifier.user
import
get_digest_subscribers
,
UserServiceException
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
...
@@ -31,39 +31,33 @@ def generate_and_send_digests(users, from_dt, to_dt):
...
@@ -31,39 +31,33 @@ def generate_and_send_digests(users, from_dt, to_dt):
of the time window for which to generate a digest.
of the time window for which to generate a digest.
"""
"""
users_by_id
=
dict
((
str
(
u
[
'id'
]),
u
)
for
u
in
users
)
users_by_id
=
dict
((
str
(
u
[
'id'
]),
u
)
for
u
in
users
)
with
closing
(
get_connection
())
as
cx
:
msgs
=
[]
msgs
=
[]
try
:
for
user_id
,
digest
in
generate_digest_content
(
users_by_id
,
from_dt
,
to_dt
)
:
with
closing
(
get_connection
())
as
cx
:
user
=
users_by_id
[
user_id
]
for
user_id
,
digest
in
generate_digest_content
(
users_by_id
,
from_dt
,
to_dt
):
# format the digest
user
=
users_by_id
[
user_id
]
text
,
html
=
render_digest
(
# format the digest
user
,
digest
,
settings
.
FORUM_DIGEST_EMAIL_TITLE
,
settings
.
FORUM_DIGEST_EMAIL_DESCRIPTION
)
text
,
html
=
render_digest
(
# send the message through our mailer
user
,
digest
,
settings
.
FORUM_DIGEST_EMAIL_TITLE
,
settings
.
FORUM_DIGEST_EMAIL_DESCRIPTION
)
msg
=
EmailMultiAlternatives
(
# send the message through our mailer
settings
.
FORUM_DIGEST_EMAIL_SUBJECT
,
msg
=
EmailMultiAlternatives
(
text
,
settings
.
FORUM_DIGEST_EMAIL_SUBJECT
,
settings
.
FORUM_DIGEST_EMAIL_SENDER
,
text
,
[
user
[
'email'
]]
settings
.
FORUM_DIGEST_EMAIL_SENDER
,
)
[
user
[
'email'
]]
msg
.
attach_alternative
(
html
,
"text/html"
)
)
msgs
.
append
(
msg
)
msg
.
attach_alternative
(
html
,
"text/html"
)
if
not
msgs
:
msgs
.
append
(
msg
)
return
if
not
msgs
:
try
:
return
cx
.
send_messages
(
msgs
)
cx
.
send_messages
(
msgs
)
except
SESMaxSendingRateExceededError
as
e
:
except
(
CommentsServiceException
,
SESMaxSendingRateExceededError
)
as
e
:
# we've tripped the per-second send rate limit. we generally
# only retry if no messages were successfully sent yet.
# rely on the django_ses auto throttle to prevent this,
if
not
any
((
getattr
(
msg
,
'extra_headers'
,
{})
.
get
(
'status'
)
==
200
for
msg
in
msgs
)):
# but in case we creep over, we can re-queue and re-try this task
raise
generate_and_send_digests
.
retry
(
exc
=
e
)
# - if and only if none of the messages in our batch were
else
:
# sent yet.
# raise right away, since we don't support partial retry
# this implementation is also non-ideal in that the data will be
raise
# fetched from the comments service again in the event of a retry.
if
not
any
((
getattr
(
msg
,
'extra_headers'
,
{})
.
get
(
'status'
)
==
200
for
msg
in
msgs
)):
raise
generate_and_send_digests
.
retry
(
exc
=
e
)
else
:
# raise right away, since we don't support partial retry
raise
def
_time_slice
(
minutes
,
now
=
None
):
def
_time_slice
(
minutes
,
now
=
None
):
"""
"""
...
...
notifier/tests/test_tasks.py
View file @
08eb44e6
...
@@ -13,7 +13,7 @@ from django.test.utils import override_settings
...
@@ -13,7 +13,7 @@ from django.test.utils import override_settings
from
mock
import
patch
,
Mock
from
mock
import
patch
,
Mock
from
notifier.tasks
import
generate_and_send_digests
,
do_forums_digests
from
notifier.tasks
import
generate_and_send_digests
,
do_forums_digests
from
notifier.pull
import
process_cs_response
from
notifier.pull
import
process_cs_response
,
CommentsServiceException
from
notifier.user
import
UserServiceException
,
DIGEST_NOTIFICATION_PREFERENCE_KEY
from
notifier.user
import
UserServiceException
,
DIGEST_NOTIFICATION_PREFERENCE_KEY
from
.utils
import
make_user_info
from
.utils
import
make_user_info
...
@@ -120,7 +120,7 @@ class TasksTestCase(TestCase):
...
@@ -120,7 +120,7 @@ class TasksTestCase(TestCase):
for
message
in
djmail
.
outbox
:
for
message
in
djmail
.
outbox
:
self
.
assertEqual
(
message
.
to
,
[
'rewritten-address@domain.org'
])
self
.
assertEqual
(
message
.
to
,
[
'rewritten-address@domain.org'
])
def
test_generate_and_send_digests_retry_
limit
(
self
):
def
test_generate_and_send_digests_retry_
ses
(
self
):
"""
"""
"""
"""
data
=
json
.
load
(
data
=
json
.
load
(
...
@@ -149,6 +149,25 @@ class TasksTestCase(TestCase):
...
@@ -149,6 +149,25 @@ class TasksTestCase(TestCase):
# should have raised
# should have raised
self
.
fail
(
'task did not retry twice before giving up'
)
self
.
fail
(
'task did not retry twice before giving up'
)
def
test_generate_and_send_digests_retry_cs
(
self
):
"""
"""
with
patch
(
'notifier.tasks.generate_digest_content'
,
side_effect
=
CommentsServiceException
(
'timed out'
)
)
as
mock_cs_call
:
# setting this here because override_settings doesn't seem to
# work on celery task configuration decorators
expected_num_tries
=
1
+
settings
.
FORUM_DIGEST_TASK_MAX_RETRIES
try
:
generate_and_send_digests
.
delay
(
[
usern
(
n
)
for
n
in
xrange
(
2
,
11
)],
datetime
.
datetime
.
now
(),
datetime
.
datetime
.
now
())
except
CommentsServiceException
as
e
:
self
.
assertEqual
(
mock_cs_call
.
call_count
,
expected_num_tries
)
else
:
# should have raised
self
.
fail
(
'task did not retry twice before giving up'
)
@override_settings
(
FORUM_DIGEST_TASK_BATCH_SIZE
=
10
)
@override_settings
(
FORUM_DIGEST_TASK_BATCH_SIZE
=
10
)
def
test_do_forums_digests
(
self
):
def
test_do_forums_digests
(
self
):
# patch _time_slice
# patch _time_slice
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment