def __getstate__(self): return { 'version': 1, 'triggers': [(obj_to_ref(trigger.__class__), trigger.__getstate__()) for trigger in self.triggers], 'jitter': self.jitter }
def __getstate__(self): # Don't allow this Job to be serialized if the function reference could not be determined if not self.func_ref: raise ValueError( 'This Job cannot be serialized since the reference to its callable (%r) could not ' 'be determined. Consider giving a textual reference (module:function name) ' 'instead.' % (self.func, )) # Instance methods cannot survive serialization as-is, so store the "self" argument # explicitly func = self.func if ismethod(func) and not isclass( func.__self__) and obj_to_ref(func) == self.func_ref: args = (func.__self__, ) + tuple(self.args) else: args = self.args return { 'version': 1, 'id': self.id, 'func': self.func_ref, 'trigger': self.trigger, 'executor': self.executor, 'args': args, 'kwargs': self.kwargs, 'name': self.name, 'misfire_grace_time': self.misfire_grace_time, 'coalesce': self.coalesce, 'max_instances': self.max_instances, 'next_run_time': self.next_run_time, 'ip': self.ip }
def __getstate__(self): # Prevents the unwanted pickling of transient or unpicklable variables state = self.__dict__.copy() state.pop('instances', None) state.pop('func', None) state.pop('_lock', None) state['func_ref'] = obj_to_ref(self.func) return state
def __init__(self, trigger, func, args, kwargs, misfire_grace_time, coalesce, name=None, max_runs=None, max_instances=1): if not trigger: raise ValueError('The trigger must not be None') if not hasattr(args, '__getitem__'): raise TypeError('args must be a list-like object') if not hasattr(kwargs, '__getitem__'): raise TypeError('kwargs must be a dict-like object') if misfire_grace_time <= 0: raise ValueError('misfire_grace_time must be a positive value') if max_runs is not None and max_runs <= 0: raise ValueError('max_runs must be a positive value') if max_instances <= 0: raise ValueError('max_instances must be a positive value') if isinstance(func, str): self.func = ref_to_obj(func) self.func_ref = func elif callable(func): self.func = func try: self.func_ref = obj_to_ref(func) except ValueError: # If this happens, this Job won't be serializable self.func_ref = None else: raise TypeError( 'func must be a callable or a textual reference to one') self._lock = Lock() self.trigger = trigger self.args = args self.kwargs = kwargs self.name = to_unicode(name or get_callable_name(self.func)) self.misfire_grace_time = misfire_grace_time self.coalesce = coalesce self.max_runs = max_runs self.max_instances = max_instances self.runs = 0 self.instances = 0
def _add(self, func, args, kwargs, queue, ftype, fargs): queue = queue or self.conf.queues[0] if queue not in self.conf.queues: raise api.InvalidQueue(queue) event = api.Event( api.Event.JOB_CREATED, queue = queue, job = adict( id = makeID(), type = ftype, options = adict(fargs), task = adict( func = obj_to_ref(func), args = args, kwargs = kwargs, ) ) ) self.broker.send(event, queue) return event.job.id
def __init__( self, trigger, func, args, kwargs, misfire_grace_time, coalesce, name=None, max_runs=None, max_instances=1 ): if not trigger: raise ValueError("The trigger must not be None") if not hasattr(args, "__getitem__"): raise TypeError("args must be a list-like object") if not hasattr(kwargs, "__getitem__"): raise TypeError("kwargs must be a dict-like object") if misfire_grace_time <= 0: raise ValueError("misfire_grace_time must be a positive value") if max_runs is not None and max_runs <= 0: raise ValueError("max_runs must be a positive value") if max_instances <= 0: raise ValueError("max_instances must be a positive value") if isinstance(func, str): self.func = ref_to_obj(func) self.func_ref = func elif callable(func): self.func = func try: self.func_ref = obj_to_ref(func) except ValueError: # If this happens, this Job won't be serializable self.func_ref = None else: raise TypeError("func must be a callable or a textual reference to one") self._lock = Lock() self.trigger = trigger self.args = args self.kwargs = kwargs self.name = to_unicode(name or get_callable_name(self.func)) self.misfire_grace_time = misfire_grace_time self.coalesce = coalesce self.max_runs = max_runs self.max_instances = max_instances self.runs = 0 self.instances = 0
def test_valid_refs(self, input, expected): assert obj_to_ref(input) == expected
def _modify(self, **changes): """ Validates the changes to the Job and makes the modifications if and only if all of them validate. """ approved = {} if 'id' in changes: value = changes.pop('id') if not isinstance(value, six.string_types): raise TypeError("id must be a nonempty string") if hasattr(self, 'id'): raise ValueError('The job ID may not be changed') approved['id'] = value if 'func' in changes or 'args' in changes or 'kwargs' in changes: func = changes.pop('func') if 'func' in changes else self.func args = changes.pop('args') if 'args' in changes else self.args kwargs = changes.pop( 'kwargs') if 'kwargs' in changes else self.kwargs if isinstance(func, six.string_types): func_ref = func func = ref_to_obj(func) elif callable(func): try: func_ref = obj_to_ref(func) except ValueError: # If this happens, this Job won't be serializable func_ref = None else: raise TypeError( 'func must be a callable or a textual reference to one') if not hasattr(self, 'name') and changes.get('name', None) is None: changes['name'] = get_callable_name(func) if isinstance(args, six.string_types) or not isinstance(args, Iterable): raise TypeError('args must be a non-string iterable') if isinstance(kwargs, six.string_types) or not isinstance(kwargs, Mapping): raise TypeError('kwargs must be a dict-like object') check_callable_args(func, args, kwargs) approved['func'] = func approved['func_ref'] = func_ref approved['args'] = args approved['kwargs'] = kwargs if 'name' in changes: value = changes.pop('name') if not value or not isinstance(value, six.string_types): raise TypeError("name must be a nonempty string") approved['name'] = value if 'misfire_grace_time' in changes: value = changes.pop('misfire_grace_time') if value is not None and (not isinstance(value, six.integer_types) or value <= 0): raise TypeError( 'misfire_grace_time must be either None or a positive integer' ) approved['misfire_grace_time'] = value if 'coalesce' in changes: value = bool(changes.pop('coalesce')) approved['coalesce'] = value if 'max_instances' in changes: value = changes.pop('max_instances') if not isinstance(value, six.integer_types) or value <= 0: raise TypeError('max_instances must be a positive integer') approved['max_instances'] = value if 'trigger' in changes: trigger = changes.pop('trigger') if not isinstance(trigger, BaseTrigger): raise TypeError('Expected a trigger instance, got %s instead' % trigger.__class__.__name__) approved['trigger'] = trigger if 'executor' in changes: value = changes.pop('executor') if not isinstance(value, six.string_types): raise TypeError('executor must be a string') approved['executor'] = value if 'next_run_time' in changes: value = changes.pop('next_run_time') approved['next_run_time'] = convert_to_datetime( value, self._scheduler.timezone, 'next_run_time') if 'ip' in changes: value = changes.pop('ip') if not isinstance(value, six.string_types): raise TypeError('ip must be a string') approved['ip'] = value if changes: raise AttributeError( 'The following are not modifiable attributes of Job: %s' % ', '.join(changes)) for key, value in six.iteritems(approved): setattr(self, key, value)
def _modify(self, **changes): """Validates the changes to the Job and makes the modifications if and only if all of them validate.""" approved = {} if 'id' in changes: value = changes.pop('id') if not isinstance(value, six.string_types): raise TypeError("id must be a nonempty string") if hasattr(self, 'id'): raise ValueError('The job ID may not be changed') approved['id'] = value if 'func' in changes or 'args' in changes or 'kwargs' in changes: func = changes.pop('func') if 'func' in changes else self.func args = changes.pop('args') if 'args' in changes else self.args kwargs = changes.pop('kwargs') if 'kwargs' in changes else self.kwargs if isinstance(func, str): func_ref = func func = ref_to_obj(func) elif callable(func): try: func_ref = obj_to_ref(func) except ValueError: # If this happens, this Job won't be serializable func_ref = None else: raise TypeError('func must be a callable or a textual reference to one') if not hasattr(self, 'name') and changes.get('name', None) is None: changes['name'] = get_callable_name(func) if isinstance(args, six.string_types) or not isinstance(args, Iterable): raise TypeError('args must be a non-string iterable') if isinstance(kwargs, six.string_types) or not isinstance(kwargs, Mapping): raise TypeError('kwargs must be a dict-like object') check_callable_args(func, args, kwargs) approved['func'] = func approved['func_ref'] = func_ref approved['args'] = args approved['kwargs'] = kwargs if 'name' in changes: value = changes.pop('name') if not value or not isinstance(value, six.string_types): raise TypeError("name must be a nonempty string") approved['name'] = value if 'misfire_grace_time' in changes: value = changes.pop('misfire_grace_time') if value is not None and (not isinstance(value, six.integer_types) or value <= 0): raise TypeError('misfire_grace_time must be either None or a positive integer') approved['misfire_grace_time'] = value if 'coalesce' in changes: value = bool(changes.pop('coalesce')) approved['coalesce'] = value if 'max_instances' in changes: value = changes.pop('max_instances') if not isinstance(value, six.integer_types) or value <= 0: raise TypeError('max_instances must be a positive integer') approved['max_instances'] = value if 'trigger' in changes: trigger = changes.pop('trigger') if not isinstance(trigger, BaseTrigger): raise TypeError('Expected a trigger instance, got %s instead' % trigger.__class__.__name__) approved['trigger'] = trigger if 'executor' in changes: value = changes.pop('executor') if not isinstance(value, six.string_types): raise TypeError('executor must be a string') approved['executor'] = value if 'next_run_time' in changes: value = changes.pop('next_run_time') approved['next_run_time'] = convert_to_datetime(value, self._scheduler.timezone, 'next_run_time') if changes: raise AttributeError('The following are not modifiable attributes of Job: %s' % ', '.join(changes)) for key, value in six.iteritems(approved): setattr(self, key, value)
def add_job(self, job): job.func_ref = obj_to_ref(job.func) job.save()
def update_job(self, job): job.func_ref = obj_to_ref(job.func) job.save()