# Path: mrq/exceptions.py
# class RetryInterrupt(_MrqInterrupt):
#     delay = None
#     queue = None
#     retry_count = 0
# 
#     def _get_exception_name(self):
#         return "%s #%s: %s seconds, %s queue" % (
#             self.__class__.__name__, self.retry_count, self.delay, self.queue
#         )
# 
# class MaxRetriesInterrupt(_MrqInterrupt):
#     pass
# 
# class AbortInterrupt(_MrqInterrupt):
#     pass
# 
# class MaxConcurrencyInterrupt(_MrqInterrupt):
#     pass
# 
# Path: mrq/utils.py
# @memoize_single_argument
# def load_class_by_path(taskpath):
#     """ Given a taskpath, returns the main task class. """
# 
#     return getattr(
#         importlib.import_module(
#             re.sub(
#                 r"\.[^.]+$",
#                 "",
#                 taskpath)),
#         re.sub(
#             r"^.*\.",
#             "",
#             taskpath))
# 
# def group_iter(iterator, n=2):
#     """ Given an iterator, it returns sub-lists made of n items.
#     (except the last that can have len < n)
# 
#     """
# 
#     # Use slices instead of an iterator when we have a flat list
#     if isinstance(iterator, list):
# 
#         length = len(iterator)
#         for i in range(int(math.ceil(old_div(float(length), n)))):
#             yield iterator[i * n: (i + 1) * n]
# 
#     else:
#         accumulator = []
#         for item in iterator:
#             accumulator.append(item)
#             if len(accumulator) == n:
#                 yield accumulator
#                 accumulator = []
# 
#         # Yield what's left
#         if len(accumulator) != 0:
#             yield accumulator


from future import standard_library
from future.builtins import str, object
from bson import ObjectId
from redis.exceptions import LockError
from .exceptions import RetryInterrupt, MaxRetriesInterrupt, AbortInterrupt, MaxConcurrencyInterrupt
from .utils import load_class_by_path, group_iter
from collections import defaultdict
from . import context
    from .queue import Queue
    from .queue import Queue
import datetime
import time
import gevent
import objgraph
import random
import gc
import traceback
import sys
import urllib.parse
import re
import linecache
import fnmatch
import encodings
import copyreg
        """ Aborts the current task mid-excution. """
        exc = AbortInterrupt()
        self._attach_original_exception(exc)
        raise exc

    def cancel(self):
        """ Markes the current job as cancelled. Doesn't interrupt it. """
        self._save_status("cancel")

    def requeue(self, queue=None, retry_count=0):
        """ Requeues the current job. Doesn't interrupt it """

        if not queue:
            if not self.data or not self.data.get("queue"):
                self.fetch(full_data={"_id": 0, "queue": 1, "path": 1})
            queue = self.data["queue"]

        self._save_status("queued", updates={
            "queue": queue,
            "datequeued": datetime.datetime.utcnow(),
            "retry_count": retry_count
        })

    def perform(self):
        """ Loads and starts the main task for this job, the saves the result. """

        if self.data is None:
            return

        context.log.debug("Starting %s(%s)" % (self.data["path"], self.data["params"]))

# Path: mrq/exceptions.py
# class RetryInterrupt(_MrqInterrupt):
#     delay = None
#     queue = None
#     retry_count = 0
# 
#     def _get_exception_name(self):
#         return "%s #%s: %s seconds, %s queue" % (
#             self.__class__.__name__, self.retry_count, self.delay, self.queue
#         )
# 
# class MaxRetriesInterrupt(_MrqInterrupt):
#     pass
# 
# class AbortInterrupt(_MrqInterrupt):
#     pass
# 
# class MaxConcurrencyInterrupt(_MrqInterrupt):
#     pass
# 
# Path: mrq/utils.py
# @memoize_single_argument
# def load_class_by_path(taskpath):
#     """ Given a taskpath, returns the main task class. """
# 
#     return getattr(
#         importlib.import_module(
#             re.sub(
#                 r"\.[^.]+$",
#                 "",
#                 taskpath)),
#         re.sub(
#             r"^.*\.",
#             "",
#             taskpath))
# 
# def group_iter(iterator, n=2):
#     """ Given an iterator, it returns sub-lists made of n items.
#     (except the last that can have len < n)
# 
#     """
# 
#     # Use slices instead of an iterator when we have a flat list
#     if isinstance(iterator, list):
# 
#         length = len(iterator)
#         for i in range(int(math.ceil(old_div(float(length), n)))):
#             yield iterator[i * n: (i + 1) * n]
# 
#     else:
#         accumulator = []
#         for item in iterator:
#             accumulator.append(item)
#             if len(accumulator) == n:
#                 yield accumulator
#                 accumulator = []
# 
#         # Yield what's left
#         if len(accumulator) != 0:
#             yield accumulator


# Path: mrq/job.py
from future import standard_library
from future.builtins import str, object
from bson import ObjectId
from redis.exceptions import LockError
from .exceptions import RetryInterrupt, MaxRetriesInterrupt, AbortInterrupt, MaxConcurrencyInterrupt
from .utils import load_class_by_path, group_iter
from collections import defaultdict
from . import context
    from .queue import Queue
    from .queue import Queue
import datetime
import time
import gevent
import objgraph
import random
import gc
import traceback
import sys
import urllib.parse
import re
import linecache
import fnmatch
import encodings
import copyreg

        """ Aborts the current task mid-excution. """
        exc = AbortInterrupt()
        self._attach_original_exception(exc)
        raise exc

    def cancel(self):
        """ Markes the current job as cancelled. Doesn't interrupt it. """
        self._save_status("cancel")

    def requeue(self, queue=None, retry_count=0):
        """ Requeues the current job. Doesn't interrupt it """

        if not queue:
            if not self.data or not self.data.get("queue"):
                self.fetch(full_data={"_id": 0, "queue": 1, "path": 1})
            queue = self.data["queue"]

        self._save_status("queued", updates={
            "queue": queue,
            "datequeued": datetime.datetime.utcnow(),
            "retry_count": retry_count
        })

    def perform(self):
        """ Loads and starts the main task for this job, the saves the result. """

        if self.data is None:
            return

        context.log.debug("Starting %s(%s)" % (self.data["path"], self.data["params"]))

        task_class = load_class_by_path(self.data["path"])