def compute_grades_for_course_v2(self, **kwargs): """ Compute grades for a set of students in the specified course. The set of students will be determined by the order of enrollment date, and limited to at most <batch_size> students, starting from the specified offset. TODO: Roll this back into compute_grades_for_course once all workers have the version with **kwargs. Sets the ESTIMATE_FIRST_ATTEMPTED flag, then calls the original task as a synchronous function. estimate_first_attempted: controls whether to unconditionally set the ESTIMATE_FIRST_ATTEMPTED waffle switch. If false or not provided, use the global value of the ESTIMATE_FIRST_ATTEMPTED waffle switch. """ if 'event_transaction_id' in kwargs: set_event_transaction_id(kwargs['event_transaction_id']) if 'event_transaction_type' in kwargs: set_event_transaction_type(kwargs['event_transaction_type']) if kwargs.get('estimate_first_attempted'): waffle().override_for_request(ESTIMATE_FIRST_ATTEMPTED, True) try: return compute_grades_for_course(kwargs['course_key'], kwargs['offset'], kwargs['batch_size']) except Exception as exc: # pylint: disable=broad-except raise self.retry(kwargs=kwargs, exc=exc)
def compute_grades_for_course_v2(self, **kwargs): """ Compute grades for a set of students in the specified course. The set of students will be determined by the order of enrollment date, and limited to at most <batch_size> students, starting from the specified offset. TODO: Roll this back into compute_grades_for_course once all workers have the version with **kwargs. Sets the ESTIMATE_FIRST_ATTEMPTED flag, then calls the original task as a synchronous function. estimate_first_attempted: controls whether to unconditionally set the ESTIMATE_FIRST_ATTEMPTED waffle switch. If false or not provided, use the global value of the ESTIMATE_FIRST_ATTEMPTED waffle switch. """ if 'event_transaction_id' in kwargs: set_event_transaction_id(kwargs['event_transaction_id']) if 'event_transaction_type' in kwargs: set_event_transaction_type(kwargs['event_transaction_type']) if kwargs.get('estimate_first_attempted'): waffle().override_for_request(ESTIMATE_FIRST_ATTEMPTED, True) try: return compute_grades_for_course(kwargs['course_key'], kwargs['offset'], kwargs['batch_size']) except Exception as exc: # pylint: disable=broad-except raise self.retry(kwargs=kwargs, exc=exc)
def recalculate_subsection_grade_v2(**kwargs): """ Updates a saved subsection grade. Arguments: user_id (int): id of applicable User object course_id (string): identifying the course usage_id (string): identifying the course block only_if_higher (boolean): indicating whether grades should be updated only if the new raw_earned is higher than the previous value. expected_modified_time (serialized timestamp): indicates when the task was queued so that we can verify the underlying data update. score_deleted (boolean): indicating whether the grade change is a result of the problem's score being deleted. event_transaction_id(string): uuid identifying the current event transaction. event_transaction_type(string): human-readable type of the event at the root of the current event transaction. """ try: course_key = CourseLocator.from_string(kwargs['course_id']) if not PersistentGradesEnabledFlag.feature_enabled(course_key): return score_deleted = kwargs['score_deleted'] scored_block_usage_key = UsageKey.from_string(kwargs['usage_id']).replace(course_key=course_key) expected_modified_time = from_timestamp(kwargs['expected_modified_time']) # The request cache is not maintained on celery workers, # where this code runs. So we take the values from the # main request cache and store them in the local request # cache. This correlates model-level grading events with # higher-level ones. set_event_transaction_id(kwargs.pop('event_transaction_id', None)) set_event_transaction_type(kwargs.pop('event_transaction_type', None)) # Verify the database has been updated with the scores when the task was # created. This race condition occurs if the transaction in the task # creator's process hasn't committed before the task initiates in the worker # process. if not _has_database_updated_with_new_score( kwargs['user_id'], scored_block_usage_key, expected_modified_time, score_deleted, ): raise _retry_recalculate_subsection_grade(**kwargs) _update_subsection_grades( course_key, scored_block_usage_key, kwargs['only_if_higher'], kwargs['user_id'], ) except Exception as exc: # pylint: disable=broad-except if not isinstance(exc, KNOWN_RETRY_ERRORS): log.info("tnl-6244 grades unexpected failure: {}. kwargs={}".format( repr(exc), kwargs )) raise _retry_recalculate_subsection_grade(exc=exc, **kwargs)
def compute_grades_for_course_v2(self, **kwargs): """ Compute grades for a set of students in the specified course. The set of students will be determined by the order of enrollment date, and limited to at most <batch_size> students, starting from the specified offset. TODO: Roll this back into compute_grades_for_course once all workers have the version with **kwargs. """ if 'event_transaction_id' in kwargs: set_event_transaction_id(kwargs['event_transaction_id']) if 'event_transaction_type' in kwargs: set_event_transaction_type(kwargs['event_transaction_type']) try: return compute_grades_for_course(kwargs['course_key'], kwargs['offset'], kwargs['batch_size']) except Exception as exc: raise self.retry(kwargs=kwargs, exc=exc)
def compute_grades_for_course_v2(self, **kwargs): """ Compute grades for a set of students in the specified course. The set of students will be determined by the order of enrollment date, and limited to at most <batch_size> students, starting from the specified offset. TODO: Roll this back into compute_grades_for_course once all workers have the version with **kwargs. """ if 'event_transaction_id' in kwargs: set_event_transaction_id(kwargs['event_transaction_id']) if 'event_transaction_type' in kwargs: set_event_transaction_type(kwargs['event_transaction_type']) try: return compute_grades_for_course(kwargs['course_key'], kwargs['offset'], kwargs['batch_size']) except Exception as exc: raise self.retry(kwargs=kwargs, exc=exc)
def _recalculate_subsection_grade(self, **kwargs): """ Updates a saved subsection grade. Keyword Arguments: user_id (int): id of applicable User object anonymous_user_id (int, OPTIONAL): Anonymous ID of the User course_id (string): identifying the course usage_id (string): identifying the course block only_if_higher (boolean): indicating whether grades should be updated only if the new raw_earned is higher than the previous value. expected_modified_time (serialized timestamp): indicates when the task was queued so that we can verify the underlying data update. score_deleted (boolean): indicating whether the grade change is a result of the problem's score being deleted. event_transaction_id (string): uuid identifying the current event transaction. event_transaction_type (string): human-readable type of the event at the root of the current event transaction. score_db_table (ScoreDatabaseTableEnum): database table that houses the changed score. Used in conjunction with expected_modified_time. """ try: course_key = CourseLocator.from_string(kwargs['course_id']) scored_block_usage_key = UsageKey.from_string(kwargs['usage_id']).replace(course_key=course_key) set_custom_metrics_for_course_key(course_key) set_custom_metric('usage_id', unicode(scored_block_usage_key)) # The request cache is not maintained on celery workers, # where this code runs. So we take the values from the # main request cache and store them in the local request # cache. This correlates model-level grading events with # higher-level ones. set_event_transaction_id(kwargs.get('event_transaction_id')) set_event_transaction_type(kwargs.get('event_transaction_type')) # Verify the database has been updated with the scores when the task was # created. This race condition occurs if the transaction in the task # creator's process hasn't committed before the task initiates in the worker # process. has_database_updated = _has_db_updated_with_new_score(self, scored_block_usage_key, **kwargs) if not has_database_updated: raise DatabaseNotReadyError _update_subsection_grades( course_key, scored_block_usage_key, kwargs['only_if_higher'], kwargs['user_id'], kwargs['score_deleted'], ) except Exception as exc: if not isinstance(exc, KNOWN_RETRY_ERRORS): log.info("tnl-6244 grades unexpected failure: {}. task id: {}. kwargs={}".format( repr(exc), self.request.id, kwargs, )) raise self.retry(kwargs=kwargs, exc=exc)
def _recalculate_subsection_grade(self, **kwargs): """ Updates a saved subsection grade. Keyword Arguments: user_id (int): id of applicable User object anonymous_user_id (int, OPTIONAL): Anonymous ID of the User course_id (string): identifying the course usage_id (string): identifying the course block only_if_higher (boolean): indicating whether grades should be updated only if the new raw_earned is higher than the previous value. expected_modified_time (serialized timestamp): indicates when the task was queued so that we can verify the underlying data update. score_deleted (boolean): indicating whether the grade change is a result of the problem's score being deleted. event_transaction_id (string): uuid identifying the current event transaction. event_transaction_type (string): human-readable type of the event at the root of the current event transaction. score_db_table (ScoreDatabaseTableEnum): database table that houses the changed score. Used in conjunction with expected_modified_time. """ try: course_key = CourseLocator.from_string(kwargs['course_id']) scored_block_usage_key = UsageKey.from_string( kwargs['usage_id']).replace(course_key=course_key) set_custom_metrics_for_course_key(course_key) set_custom_metric('usage_id', unicode(scored_block_usage_key)) # The request cache is not maintained on celery workers, # where this code runs. So we take the values from the # main request cache and store them in the local request # cache. This correlates model-level grading events with # higher-level ones. set_event_transaction_id(kwargs.get('event_transaction_id')) set_event_transaction_type(kwargs.get('event_transaction_type')) # Verify the database has been updated with the scores when the task was # created. This race condition occurs if the transaction in the task # creator's process hasn't committed before the task initiates in the worker # process. has_database_updated = _has_db_updated_with_new_score( self, scored_block_usage_key, **kwargs) if not has_database_updated: raise DatabaseNotReadyError _update_subsection_grades( course_key, scored_block_usage_key, kwargs['only_if_higher'], kwargs['user_id'], kwargs['score_deleted'], ) except Exception as exc: # pylint: disable=broad-except if not isinstance(exc, KNOWN_RETRY_ERRORS): log.info( "tnl-6244 grades unexpected failure: {}. task id: {}. kwargs={}" .format( repr(exc), self.request.id, kwargs, )) raise self.retry(kwargs=kwargs, exc=exc)