Moving the update course and subsection grades to async task

[LEARNER-5123]

The update course and subsection grades method was causing a DB lock
on other requsets.  This should be performed in the background and given
its own async task.
This commit is contained in:
Albert St. Aubin
2018-05-07 09:56:25 -04:00
committed by Alex Dusenbery
parent 2daaea9744
commit 787653e793
2 changed files with 39 additions and 8 deletions

View File

@@ -26,7 +26,11 @@ from ..constants import ScoreDatabaseTableEnum
from ..course_grade_factory import CourseGradeFactory
from .. import events
from ..scores import weighted_score
from ..tasks import RECALCULATE_GRADE_DELAY_SECONDS, recalculate_subsection_grade_v3
from ..tasks import (
RECALCULATE_GRADE_DELAY_SECONDS,
recalculate_subsection_grade_v3,
recalculate_course_and_subsection_grades_for_user
)
log = getLogger(__name__)
@@ -241,10 +245,9 @@ def recalculate_course_and_subsection_grades(sender, user, course_key, **kwargs)
Updates a saved course grade, forcing the subsection grades
from which it is calculated to update along the way.
"""
previous_course_grade = CourseGradeFactory().read(user, course_key=course_key)
if previous_course_grade and previous_course_grade.attempted:
CourseGradeFactory().update(
recalculate_course_and_subsection_grades_for_user.apply_async(
kwargs=dict(
user=user,
course_key=course_key,
force_update_subsections=True
course_key=course_key
)
)

View File

@@ -94,7 +94,7 @@ def compute_grades_for_course_v2(self, **kwargs):
try:
return compute_grades_for_course(kwargs['course_key'], kwargs['offset'], kwargs['batch_size'])
except Exception as exc: # pylint: disable=broad-except
except Exception as exc:
raise self.retry(kwargs=kwargs, exc=exc)
@@ -115,6 +115,34 @@ def compute_grades_for_course(course_key, offset, batch_size, **kwargs): # pyli
raise result.error
@task(
bind=True,
time_limit=SUBSECTION_GRADE_TIMEOUT_SECONDS,
max_retries=2,
default_retry_delay=RETRY_DELAY_SECONDS,
routing_key=settings.RECALCULATE_GRADES_ROUTING_KEY
)
def recalculate_course_and_subsection_grades_for_user(self, **kwargs): # pylint: disable=unused-argument
"""
Recalculates the course grade and all subsection grades
for the given ``user`` and ``course_key`` keyword arguments.
"""
user = kwargs.get('user')
course_key = kwargs.get('course_key')
if not user or course_key:
message = 'recalculate_course_and_subsection_grades_for_user missing "user" or "course_key" kwargs from {}'
log.error(message.format(kwargs))
previous_course_grade = CourseGradeFactory().read(user, course_key=course_key)
if previous_course_grade and previous_course_grade.attempted:
CourseGradeFactory().update(
user=user,
course_key=course_key,
force_update_subsections=True
)
@task(
bind=True,
base=LoggedPersistOnFailureTask,
@@ -185,7 +213,7 @@ def _recalculate_subsection_grade(self, **kwargs):
kwargs['user_id'],
kwargs['score_deleted'],
)
except Exception as exc: # pylint: disable=broad-except
except Exception as exc:
if not isinstance(exc, KNOWN_RETRY_ERRORS):
log.info("tnl-6244 grades unexpected failure: {}. task id: {}. kwargs={}".format(
repr(exc),