Example #1
0
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)
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
    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)
Example #6
0
    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'])
Example #7
0
    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)
Example #8
0
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)
Example #9
0
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)
Example #10
0
    def test_returns_instance(self):
        call = ScheduledCall.from_db(self.schedule)

        entry = call.as_schedule_entry()

        self.assertTrue(isinstance(entry, celery.beat.ScheduleEntry))
Example #11
0
    def test_preserves_id(self):
        call = ScheduledCall.from_db(self.schedule)

        self.assertEqual(call.id, '529f4bd93de3a31d0ec77338')
Example #12
0
    def test_returns_instance(self):
        call = ScheduledCall.from_db(self.schedule)

        self.assertTrue(isinstance(call, ScheduledCall))