Commit 529889f3 by Eric Fischer

Recalculate Subsection Grade task retry logic

The task will now be retried if an IntegrityError is encountered, up to
the default of 3 times. Test included.

TNL-5739
parent 6ccb74c7
...@@ -5,6 +5,7 @@ This module contains tasks for asynchronous execution of grade updates. ...@@ -5,6 +5,7 @@ This module contains tasks for asynchronous execution of grade updates.
from celery import task from celery import task
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.utils import IntegrityError
from lms.djangoapps.course_blocks.api import get_course_blocks from lms.djangoapps.course_blocks.api import get_course_blocks
from lms.djangoapps.courseware.courses import get_course_by_id from lms.djangoapps.courseware.courses import get_course_by_id
...@@ -17,7 +18,7 @@ from .transformer import GradesTransformer ...@@ -17,7 +18,7 @@ from .transformer import GradesTransformer
from .new.subsection_grade import SubsectionGradeFactory from .new.subsection_grade import SubsectionGradeFactory
@task(routing_key=settings.RECALCULATE_GRADES_ROUTING_KEY) @task(default_retry_delay=30, routing_key=settings.RECALCULATE_GRADES_ROUTING_KEY)
def recalculate_subsection_grade(user_id, course_id, usage_id): def recalculate_subsection_grade(user_id, course_id, usage_id):
""" """
Updates a saved subsection grade. Updates a saved subsection grade.
...@@ -43,6 +44,7 @@ def recalculate_subsection_grade(user_id, course_id, usage_id): ...@@ -43,6 +44,7 @@ def recalculate_subsection_grade(user_id, course_id, usage_id):
set() set()
) )
try:
for subsection_usage_key in subsections_to_update: for subsection_usage_key in subsections_to_update:
transformed_subsection_structure = get_course_blocks( transformed_subsection_structure = get_course_blocks(
student, student,
...@@ -52,3 +54,5 @@ def recalculate_subsection_grade(user_id, course_id, usage_id): ...@@ -52,3 +54,5 @@ def recalculate_subsection_grade(user_id, course_id, usage_id):
subsection_grade_factory.update( subsection_grade_factory.update(
transformed_subsection_structure[subsection_usage_key], transformed_subsection_structure transformed_subsection_structure[subsection_usage_key], transformed_subsection_structure
) )
except IntegrityError as exc:
raise recalculate_subsection_grade.retry(args=[user_id, course_id, usage_id], exc=exc)
...@@ -4,6 +4,7 @@ Tests for the functionality and infrastructure of grades tasks. ...@@ -4,6 +4,7 @@ Tests for the functionality and infrastructure of grades tasks.
import ddt import ddt
from django.conf import settings from django.conf import settings
from django.db.utils import IntegrityError
from mock import patch from mock import patch
from unittest import skip from unittest import skip
...@@ -154,3 +155,20 @@ class RecalculateSubsectionGradeTest(ModuleStoreTestCase): ...@@ -154,3 +155,20 @@ class RecalculateSubsectionGradeTest(ModuleStoreTestCase):
self.score_changed_kwargs['usage_id'], self.score_changed_kwargs['usage_id'],
) )
) )
@patch('lms.djangoapps.grades.tasks.recalculate_subsection_grade.retry')
@patch('lms.djangoapps.grades.new.subsection_grade.SubsectionGradeFactory.update')
def test_retry_on_integrity_error(self, mock_update, mock_retry):
"""
Ensures that tasks will be retried if IntegrityErrors are encountered.
"""
self.set_up_course()
mock_update.side_effect = IntegrityError("WHAMMY")
recalculate_subsection_grade.apply(
args=(
self.score_changed_kwargs['user_id'],
self.score_changed_kwargs['course_id'],
self.score_changed_kwargs['usage_id'],
)
)
self.assertTrue(mock_retry.called)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment