def perform_job(self, job):
        """ Wraps a job.perform() call with timeout logic and exception handlers.

            This is the first call happening inside the greenlet.
        """

        if self.config["trace_memory"]:
            job.trace_memory_start()

        set_current_job(job)

        gevent_timeout = None
        if job.timeout:

            gevent_timeout = gevent.Timeout(
                job.timeout,
                TimeoutInterrupt(
                    'Job exceeded maximum timeout value in greenlet (%d seconds).' %
                    job.timeout
                )
            )

            gevent_timeout.start()

        try:
            job.perform()

        except RetryInterrupt:
            self.log.error("Caught retry")
            job.save_retry(sys.exc_info()[1])

        except MaxRetriesInterrupt:
            self.log.error("Max retries reached")
            job._save_status("maxretries", exception=True)

        except AbortInterrupt:
            self.log.error("Caught abort")
            job.save_abort()

        except TimeoutInterrupt:
            self.log.error(job.timeout % "Job timeouted after %s seconds")
            job._save_status("timeout", exception=True)

        except JobInterrupt:
            self.log.error("Job interrupted")
            job._save_status("interrupt", exception=True)

        except Exception:
            self.log.error("Job failed")
            job._save_status("failed", exception=True)

        finally:

            if gevent_timeout:
                gevent_timeout.cancel()

            set_current_job(None)

            self.done_jobs += 1

            if self.config["trace_memory"]:
                job.trace_memory_stop()
dataset/ETHPy150Open pricingassistant/mrq/mrq/worker.py/Worker.perform_job/swapped operands of `%`