feat: explain certificate delay seconds and make it overrideable

this appears to be a throttling method on first glance but is instead
an async task handling hack, explain it

and then provide a way to override it for tight control of timing
while regenerating multiple certs
This commit is contained in:
Andy Shultz
2021-10-26 13:35:01 -04:00
parent 41fec1c58e
commit 1be408046b
2 changed files with 18 additions and 9 deletions

View File

@@ -27,7 +27,7 @@ from openedx.core.djangoapps.content.course_overviews.api import get_course_over
log = logging.getLogger(__name__)
def generate_certificate_task(user, course_key, generation_mode=None):
def generate_certificate_task(user, course_key, generation_mode=None, delay_seconds=CERTIFICATE_DELAY_SECONDS):
"""
Create a task to generate a certificate for this user in this course run, if the user is eligible and a certificate
can be generated.
@@ -38,13 +38,16 @@ def generate_certificate_task(user, course_key, generation_mode=None):
if is_on_certificate_allowlist(user, course_key):
log.info(f'User {user.id} is on the allowlist for {course_key}. Attempt will be made to generate an allowlist '
f'certificate.')
return generate_allowlist_certificate_task(user, course_key, generation_mode)
return generate_allowlist_certificate_task(user, course_key, generation_mode=generation_mode,
delay_seconds=delay_seconds)
log.info(f'Attempt will be made to generate course certificate for user {user.id} : {course_key}')
return _generate_regular_certificate_task(user, course_key, generation_mode)
return _generate_regular_certificate_task(user, course_key, generation_mode=generation_mode,
delay_seconds=delay_seconds)
def generate_allowlist_certificate_task(user, course_key, generation_mode=None):
def generate_allowlist_certificate_task(user, course_key, generation_mode=None,
delay_seconds=CERTIFICATE_DELAY_SECONDS):
"""
Create a task to generate an allowlist certificate for this user in this course run.
"""
@@ -52,7 +55,8 @@ def generate_allowlist_certificate_task(user, course_key, generation_mode=None):
course_grade = _get_course_grade(user, course_key)
if _can_generate_allowlist_certificate(user, course_key, enrollment_mode):
return _generate_certificate_task(user=user, course_key=course_key, enrollment_mode=enrollment_mode,
course_grade=course_grade, generation_mode=generation_mode)
course_grade=course_grade, generation_mode=generation_mode,
delay_seconds=delay_seconds)
status = _set_allowlist_cert_status(user, course_key, enrollment_mode, course_grade)
if status is not None:
@@ -61,7 +65,7 @@ def generate_allowlist_certificate_task(user, course_key, generation_mode=None):
return False
def _generate_regular_certificate_task(user, course_key, generation_mode=None):
def _generate_regular_certificate_task(user, course_key, generation_mode=None, delay_seconds=CERTIFICATE_DELAY_SECONDS):
"""
Create a task to generate a regular (non-allowlist) certificate for this user in this course run, if the user is
eligible and a certificate can be generated.
@@ -70,7 +74,8 @@ def _generate_regular_certificate_task(user, course_key, generation_mode=None):
course_grade = _get_course_grade(user, course_key)
if _can_generate_regular_certificate(user, course_key, enrollment_mode, course_grade):
return _generate_certificate_task(user=user, course_key=course_key, enrollment_mode=enrollment_mode,
course_grade=course_grade, generation_mode=generation_mode)
course_grade=course_grade, generation_mode=generation_mode,
delay_seconds=delay_seconds)
status = _set_regular_cert_status(user, course_key, enrollment_mode, course_grade)
if status is not None:
@@ -79,7 +84,8 @@ def _generate_regular_certificate_task(user, course_key, generation_mode=None):
return False
def _generate_certificate_task(user, course_key, enrollment_mode, course_grade, status=None, generation_mode=None):
def _generate_certificate_task(user, course_key, enrollment_mode, course_grade, status=None, generation_mode=None,
delay_seconds=CERTIFICATE_DELAY_SECONDS):
"""
Create a task to generate a certificate
"""
@@ -98,7 +104,7 @@ def _generate_certificate_task(user, course_key, enrollment_mode, course_grade,
if generation_mode is not None:
kwargs['generation_mode'] = generation_mode
generate_certificate.apply_async(countdown=CERTIFICATE_DELAY_SECONDS, kwargs=kwargs)
generate_certificate.apply_async(countdown=delay_seconds, kwargs=kwargs)
return True

View File

@@ -15,6 +15,9 @@ from lms.djangoapps.certificates.generation import generate_course_certificate
log = getLogger(__name__)
User = get_user_model()
# Certificate generation is delayed in case the caller is still completing their changes
# (for example a certificate regeneration reacting to a post save rather than post commit signal)
CERTIFICATE_DELAY_SECONDS = 2