def increment_failure_count(schedule_id): """ Increment the number of consecutive failures, and if it has met or exceeded the threshold, disable the schedule. :param schedule_id: ID of the schedule whose count should be incremented :type schedule_id: str """ try: spec = {'_id': ObjectId(schedule_id)} except InvalidId: raise exceptions.InvalidValue(['schedule_id']) delta = { '$inc': {'consecutive_failures': 1}, '$set': {'last_updated': time.time()}, } schedule = ScheduledCall.get_collection().find_and_modify( query=spec, update=delta, new=True) if schedule: scheduled_call = ScheduledCall.from_db(schedule) if scheduled_call.failure_threshold is None or not scheduled_call.enabled: return if scheduled_call.consecutive_failures >= scheduled_call.failure_threshold: _logger.info(_('disabling schedule %(id)s with %(count)d consecutive failures') % { 'id': schedule_id, 'count': scheduled_call.consecutive_failures }) delta = {'$set': { 'enabled': False, 'last_updated': time.time(), }} ScheduledCall.get_collection().update(spec, delta)
def update(schedule_id, delta): """ Updates the schedule with unique ID schedule_id. This only allows updating of fields in ScheduledCall.USER_UPDATE_FIELDS. :param schedule_id: a unique ID for a schedule :type schedule_id: basestring :param delta: a dictionary of keys with values that should be modified on the schedule. :type delta: dict :return: instance of ScheduledCall representing the post-update state :rtype ScheduledCall :raise exceptions.UnsupportedValue :raise exceptions.MissingResource """ unknown_keys = set(delta.keys()) - ScheduledCall.USER_UPDATE_FIELDS if unknown_keys: raise exceptions.UnsupportedValue(list(unknown_keys)) delta['last_updated'] = time.time() try: spec = {'_id': ObjectId(schedule_id)} except InvalidId: raise exceptions.InvalidValue(['schedule_id']) schedule = ScheduledCall.get_collection().find_and_modify( query=spec, update={'$set': delta}, safe=True, new=True) if schedule is None: raise exceptions.MissingResource(schedule_id=schedule_id) return ScheduledCall.from_db(schedule)
def test_values(self): schedule = bson.SON(SCHEDULE) call = ScheduledCall.from_db(schedule) result = call.as_dict() self.assertEqual(result['_id'], call.id) for k, v in SCHEDULE.items(): self.assertEqual(v, result[k]) self.assertTrue('next_run' in result)
def test_values(self): schedule = bson.SON(SCHEDULE) call = ScheduledCall.from_db(schedule) as_dict = call.as_dict() result = call.for_display() for k, v in result.items(): if k not in ['schedule', 'iso_schedule']: self.assertEqual(v, as_dict[k]) self.assertEqual(result['schedule'], as_dict['iso_schedule'])
def test_values(self): call = ScheduledCall.from_db(self.schedule) entry = call.as_schedule_entry() self.assertEqual(entry._scheduled_call, call) self.assertTrue(isinstance(entry.schedule, CelerySchedule)) self.assertEqual(entry.args, call.args) self.assertEqual(entry.kwargs, call.kwargs) self.assertEqual(entry.name, call.name) self.assertEqual(entry.task, call.task) self.assertEqual(entry.options, call.options) self.assertEqual(entry.last_run_at, dateutils.parse_iso8601_datetime(call.last_run_at)) self.assertFalse(entry.schedule.relative)
def update(schedule_id, delta): """ Updates the schedule with unique ID schedule_id. This only allows updating of fields in ScheduledCall.USER_UPDATE_FIELDS. :param schedule_id: a unique ID for a schedule :type schedule_id: basestring :param delta: a dictionary of keys with values that should be modified on the schedule. :type delta: dict :return: instance of ScheduledCall representing the post-update state :rtype ScheduledCall :raise exceptions.UnsupportedValue :raise exceptions.MissingResource """ unknown_keys = set(delta.keys()) - ScheduledCall.USER_UPDATE_FIELDS if unknown_keys: raise exceptions.UnsupportedValue(list(unknown_keys)) delta['last_updated'] = time.time() # bz 1139703 - if we update iso_schedule, update the pickled object as well if 'iso_schedule' in delta: interval, start_time, occurrences = dateutils.parse_iso8601_interval( delta['iso_schedule']) delta['schedule'] = pickle.dumps(CelerySchedule(interval)) # set first_run and next_run so that the schedule update will take effect new_schedule_call = ScheduledCall(delta['iso_schedule'], 'dummytaskname') delta['first_run'] = new_schedule_call.first_run delta['next_run'] = new_schedule_call.next_run try: spec = {'_id': ObjectId(schedule_id)} except InvalidId: # During schedule update, MissingResource should be raised even if # schedule_id is invalid object_id. raise exceptions.MissingResource(schedule_id=schedule_id) schedule = ScheduledCall.get_collection().find_and_modify( query=spec, update={'$set': delta}, safe=True, new=True) if schedule is None: raise exceptions.MissingResource(schedule_id=schedule_id) return ScheduledCall.from_db(schedule)
def update(schedule_id, delta): """ Updates the schedule with unique ID schedule_id. This only allows updating of fields in ScheduledCall.USER_UPDATE_FIELDS. :param schedule_id: a unique ID for a schedule :type schedule_id: basestring :param delta: a dictionary of keys with values that should be modified on the schedule. :type delta: dict :return: instance of ScheduledCall representing the post-update state :rtype ScheduledCall :raise exceptions.UnsupportedValue :raise exceptions.MissingResource """ unknown_keys = set(delta.keys()) - ScheduledCall.USER_UPDATE_FIELDS if unknown_keys: raise exceptions.UnsupportedValue(list(unknown_keys)) delta['last_updated'] = time.time() # bz 1139703 - if we update iso_schedule, update the pickled object as well if 'iso_schedule' in delta: interval, start_time, occurrences = dateutils.parse_iso8601_interval(delta['iso_schedule']) delta['schedule'] = pickle.dumps(CelerySchedule(interval)) # set first_run and next_run so that the schedule update will take effect new_schedule_call = ScheduledCall(delta['iso_schedule'], 'dummytaskname') delta['first_run'] = new_schedule_call.first_run delta['next_run'] = new_schedule_call.next_run try: spec = {'_id': ObjectId(schedule_id)} except InvalidId: # During schedule update, MissingResource should be raised even if # schedule_id is invalid object_id. raise exceptions.MissingResource(schedule_id=schedule_id) schedule = ScheduledCall.get_collection().find_and_modify( query=spec, update={'$set': delta}, new=True) if schedule is None: raise exceptions.MissingResource(schedule_id=schedule_id) return ScheduledCall.from_db(schedule)
def test_returns_instance(self): call = ScheduledCall.from_db(self.schedule) entry = call.as_schedule_entry() self.assertTrue(isinstance(entry, celery.beat.ScheduleEntry))
def test_preserves_id(self): call = ScheduledCall.from_db(self.schedule) self.assertEqual(call.id, '529f4bd93de3a31d0ec77338')
def test_returns_instance(self): call = ScheduledCall.from_db(self.schedule) self.assertTrue(isinstance(call, ScheduledCall))