| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- from apscheduler.triggers.base import BaseTrigger
- from apscheduler.util import obj_to_ref, ref_to_obj
- class BaseCombiningTrigger(BaseTrigger):
- __slots__ = ('triggers', 'jitter')
- def __init__(self, triggers, jitter=None):
- self.triggers = triggers
- self.jitter = jitter
- def __getstate__(self):
- return {
- 'version': 1,
- 'triggers': [(obj_to_ref(trigger.__class__), trigger.__getstate__())
- for trigger in self.triggers],
- 'jitter': self.jitter
- }
- def __setstate__(self, state):
- if state.get('version', 1) > 1:
- raise ValueError(
- 'Got serialized data for version %s of %s, but only versions up to 1 can be '
- 'handled' % (state['version'], self.__class__.__name__))
- self.jitter = state['jitter']
- self.triggers = []
- for clsref, state in state['triggers']:
- cls = ref_to_obj(clsref)
- trigger = cls.__new__(cls)
- trigger.__setstate__(state)
- self.triggers.append(trigger)
- def __repr__(self):
- return '<{}({}{})>'.format(self.__class__.__name__, self.triggers,
- ', jitter={}'.format(self.jitter) if self.jitter else '')
- class AndTrigger(BaseCombiningTrigger):
- """
- Always returns the earliest next fire time that all the given triggers can agree on.
- The trigger is considered to be finished when any of the given triggers has finished its
- schedule.
- Trigger alias: ``and``
- :param list triggers: triggers to combine
- :param int|None jitter: delay the job execution by ``jitter`` seconds at most
- """
- __slots__ = ()
- def get_next_fire_time(self, previous_fire_time, now):
- while True:
- fire_times = [trigger.get_next_fire_time(previous_fire_time, now)
- for trigger in self.triggers]
- if None in fire_times:
- return None
- elif min(fire_times) == max(fire_times):
- return self._apply_jitter(fire_times[0], self.jitter, now)
- else:
- now = max(fire_times)
- def __str__(self):
- return 'and[{}]'.format(', '.join(str(trigger) for trigger in self.triggers))
- class OrTrigger(BaseCombiningTrigger):
- """
- Always returns the earliest next fire time produced by any of the given triggers.
- The trigger is considered finished when all the given triggers have finished their schedules.
- Trigger alias: ``or``
- :param list triggers: triggers to combine
- :param int|None jitter: delay the job execution by ``jitter`` seconds at most
- .. note:: Triggers that depends on the previous fire time, such as the interval trigger, may
- seem to behave strangely since they are always passed the previous fire time produced by
- any of the given triggers.
- """
- __slots__ = ()
- def get_next_fire_time(self, previous_fire_time, now):
- fire_times = [trigger.get_next_fire_time(previous_fire_time, now)
- for trigger in self.triggers]
- fire_times = [fire_time for fire_time in fire_times if fire_time is not None]
- if fire_times:
- return self._apply_jitter(min(fire_times), self.jitter, now)
- else:
- return None
- def __str__(self):
- return 'or[{}]'.format(', '.join(str(trigger) for trigger in self.triggers))
|