Esempio n. 1
0
 def callable(self, value):
     # can't pickle/persist methods by default as of this writing, so we
     # add the sugar ourselves.  In future, would like for args to be
     # potentially methods of persistent objects too...
     if self.status != zc. async .interfaces.NEW:
         raise zc. async .interfaces.BadStatusError(
             'can only set callable when a job has NEW, PENDING, or '
             'ASSIGNED status')
Esempio n. 2
0
 def fail(self, e=None):
     # something may have fallen over the last time this was called, so we
     # are careful to only store the error if we're not in the CALLBACKS
     # status.
     callback = True
     status = self.status
     if status in (zc. async .interfaces.COMPLETED,
                   zc. async .interfaces.ACTIVE):
         raise zc. async .interfaces.BadStatusError(
             'can only call fail on a job with NEW, PENDING, or ASSIGNED '
             'status')  # ...or CALLBACKS, but that's because of
Esempio n. 3
0
    def __call__(self, *args, **kwargs):
        statuses = (zc. async .interfaces.NEW, zc. async .interfaces.ASSIGNED)
        if self.status not in statuses:
            raise zc. async .interfaces.BadStatusError(
                'can only call a job with NEW or ASSIGNED status')
        tm = transaction.interfaces.ITransactionManager(self)

        def prepare():
            self._check_reassigned(statuses)
            self._status_id = 1  # ACTIVE
            self._active_start = datetime.datetime.now(pytz.UTC)
            effective_args = list(args)
            effective_args[0:0] = self.args
            effective_kwargs = dict(self.kwargs)
            effective_kwargs.update(kwargs)
            return effective_args, effective_kwargs

        identifier = 'preparing for call of %r' % (self, )
        effective_args, effective_kwargs = zc. async .utils.never_fail(
            prepare, identifier, tm)
        # this is the calling code.  It is complex and long because it is
        # trying both to handle exceptions reasonably, and to honor the
        # IRetryPolicy interface for those exceptions.
        data_cache = {}
        res = None
        while 1:
            zc. async .local.job = self  # we do this in the loop for paranoia
            try:
                setup_info = self.setUp()
                res = self.callable(*effective_args, **effective_kwargs)
            except zc. async .utils.EXPLOSIVE_ERRORS:
                tm.abort()
                zc. async .utils.try_five_times(
                    lambda: self.tearDown(setup_info),
                    'tearDown for %r' % self,
                    tm,
                    commit=False)
                raise
            except:
Esempio n. 4
0
 def resumeCallbacks(self):
     # should be called within a job that has a RetryCommonForever policy
     if self.status != zc. async .interfaces.CALLBACKS:
         raise zc. async .interfaces.BadStatusError(
             'can only resumeCallbacks on a job with CALLBACKS status')
Esempio n. 5
0
 def handleCallbackInterrupt(self, caller):
     if self.status != zc. async .interfaces.ACTIVE:
         raise zc. async .interfaces.BadStatusError(
             'can only handleCallbackInterrupt on a job with ACTIVE status')
Esempio n. 6
0
 def begin_by(self, value):
     if self.status not in (zc. async .interfaces.PENDING,
                            zc. async .interfaces.NEW):
         raise zc. async .interfaces.BadStatusError(
             'can only set begin_by when a job has NEW or PENDING status')
Esempio n. 7
0
 def begin_after(self, value):
     if self.status != zc. async .interfaces.NEW:
         raise zc. async .interfaces.BadStatusError(
             'can only set begin_after when a job has NEW status')
Esempio n. 8
0
        return self._quota_names

    @rwproperty.setproperty
    def quota_names(self, value):
        if isinstance(value, basestring):
            raise TypeError('provide an iterable of names')
        status = self.status
        if status != zc. async .interfaces.NEW:
            if status == zc. async .interfaces.PENDING:
                quotas = self.queue.quotas
                for name in value:
                    if name not in quotas:
                        raise ValueError('unknown quota name', name)
            else:
                raise zc. async .interfaces.BadStatusError(
                    'can only set quota_names when a job has NEW or PENDING '
                    'status')
        self._quota_names = tuple(value)

    @property
    def begin_after(self):
        return self._begin_after

    @rwproperty.setproperty
    def begin_after(self, value):
        if self.status != zc. async .interfaces.NEW:
            raise zc. async .interfaces.BadStatusError(
                'can only set begin_after when a job has NEW status')
        if value is not None:
            if value.tzinfo is None:
                raise ValueError('cannot use timezone-naive values')