Пример #1
0
    def execute(self):
        """Executes an actor and yields the results when its finished.

        Calls an actors private _execute() method and either returns the result
        (through gen.Return) or handles any exceptions that are raised.

        RecoverableActorFailure exceptions are potentially swallowed up (and
        warned) if the self._warn_on_failure flag is set. Otherwise, they're
        logged and re-raised. All other ActorException exceptions are caught,
        logged and re-raised.

        We have a generic catch-all exception handling block as well, because
        third party Actor classes may or may not catch all appropriate
        exceptions. This block is mainly here to prevent the entire app from
        failing due to a poorly written Actor.

        Raises:
            gen.Return(result)
        """
        self.log.debug('Beginning')

        # Any exception thats raised by an actors _execute() method will
        # automatically cause actor failure and we return right away.
        result = None

        if not self._check_condition():
            self.log.warning('Skipping execution. Condition: %s' %
                             self._condition)
            raise gen.Return()

        try:
            result = yield self.timeout(self._execute)
        except exceptions.ActorException as e:
            # If exception is not RecoverableActorFailure
            # or if warn_on_failure is not set, then escalate.
            recover = isinstance(e, exceptions.RecoverableActorFailure)
            if not recover or not self._warn_on_failure:
                self.log.critical(e)
                raise

            # Otherwise - flag this failure as a warning, and continue
            self.log.warning(e)
            self.log.warning('Continuing execution even though a failure was '
                             'detected (warn_on_failure=%s)' %
                             self._warn_on_failure)
        except Exception as e:
            # We don't like general exception catch clauses like this, but
            # because actors can be written by third parties and automatically
            # imported, its impossible for us to catch every exception
            # possible. This is a failsafe thats meant to throw a strong
            # warning.
            log.critical('Unexpected exception caught! '
                         'Please contact the author (%s) and provide them '
                         'with this stacktrace' %
                         sys.modules[self.__module__].__author__)
            self.log.exception(e)
            raise exceptions.ActorException(e)
        else:
            self.log.debug('Finished successfully, return value: %s' % result)

        # If we got here, we're exiting the actor cleanly and moving on.
        raise gen.Return(result)
Пример #2
0
 def raise_exc():
     raise exceptions.ActorException('Test')