Example #1
0
    def get_task(self, task_uid):
        """Returns the task with the given task uid. Retrieves the task from
        the local pool if exists. Otherwise, fetches the task from the Queue
        server via POST
        :param task_uid: task's unique id
        :return: the task from the queue
        :rtype: queue.QueueTask
        """
        # Search first in our local pool
        task_uid = get_task_uid(task_uid)
        task = filter(lambda t: t.task_uid == task_uid, self._tasks)
        if task:
            return copy.deepcopy(task[0])

        # Ask the queue server (maybe we are searching for a failed)
        task_uid = get_task_uid(task_uid)
        try:
            task = self._post(task_uid)
        except HTTPError as e:
            # If not found (404), return None instead of exception to make this
            # utility to behave as server's
            if e.response.status_code != 404:
                raise e
        except Exception as e:
            raise e
        if not task:
            return None
        return to_task(task)
Example #2
0
 def delete(self, task):
     """Removes a task from the queue
     :param task: task's unique id (task_uid) or QueueTask object
     """
     with self.__lock:
         task_uid = get_task_uid(task)
         self._delete(task_uid)
Example #3
0
 def has_task(self, task):
     """Returns whether the queue contains a given task
     :param task: task's unique id (task_uid) or QueueTask object
     :return: True if the queue contains the task
     :rtype: bool
     """
     if self.get_task(get_task_uid(task)):
         return True
     return False
Example #4
0
 def timeout(self, task):
     """Notifies the queue that the processing of the task timed out. Sends a
     POST to the queue server and updates the local pool accordingly
     :param task: task's unique id (task_uid) or QueueTask object
     """
     payload = {"task_uid": get_task_uid(task)}
     self._post("timeout", payload=payload)
     # Always sync on timeout (task might be re-queued or failed by server)
     self.sync()
Example #5
0
    def done(self, task):
        """Notifies the queue that the task has been processed successfully.
        Sends a POST to the queue server and removes the task from local pool
        :param task: task's unique id (task_uid) or QueueTask object
        """
        # Tell the queue server the task is done
        task_uid = get_task_uid(task)
        payload = {"task_uid": task_uid}
        err = None
        try:
            self._post("done", payload=payload)
        except (ConnectionError, Timeout, TooManyRedirects) as e:
            err = "{}: {}".format(type(e).__name__, str(e))

        except HTTPError as e:
            status = e.response.status_code or 500
            if status < 500 or status >= 600:
                raise e
            message = e.response.json() or {}
            err = "{}: {}".format(status, message.get("message", str(e)))

        except APIError as e:
            if e.status < 500 or e.status >= 600:
                raise e
            err = "{}: {}".format(e.status, e.message)

        if err:
            # Not able to tell the queue server. Keep it locally so it can be
            # synchronized as soon as we have connectivity again
            logger.warn(err)
            capi.get_request().response.setStatus(200)
            task_uid = get_task_uid(task_uid)
            tasks = filter(lambda t: t.task_uid == task_uid, self._tasks)
            if tasks:
                task = tasks[0]
            else:
                self._tasks.append(task)
            task.update({"offline": "done"})
            return

        # Remove from local pool
        self._tasks = filter(lambda t: t.task_uid != task_uid, self._tasks)
Example #6
0
 def fail(self, task, error_message=None):
     """Notifies the queue that the processing of the task failed. Sends a
     POST to the queue server and updates the local pool accordingly
     :param task: task's unique id (task_uid) or QueueTask object
     :param error_message: (Optional) the error/traceback
     """
     task_uid = get_task_uid(task)
     payload = {"task_uid": task_uid, "error_message": error_message or ""}
     self._post("fail", payload=payload)
     # Always sync on fail (task might be re-queued or failed by server)
     self.sync()
Example #7
0
def get(context, request, task_uid):  # noqa
    """Returns a JSON representation of the task with the specified task uid
    """
    # Get the task
    task = get_task(task_uid)

    # Digest the task and return
    zeo = get_post_zeo()
    task_uid = get_task_uid(task, default="none")
    logger.info("::server.get: {} [{}]".format(task_uid, zeo))
    return get_task_info(task, complete=True)
Example #8
0
 def get_task(self, task_uid):
     """Returns the task with the given task uid
     :param task_uid: task's unique id
     :return: the task from the queue
     :rtype: queue.QueueTask
     """
     task_uid = get_task_uid(task_uid)
     for task in self._tasks:
         if task.task_uid == task_uid:
             return copy.deepcopy(task)
     return None
Example #9
0
def pop(context, request):  # noqa
    """Pops the next task from the queue, if any. Popped task is no longer
    available in the queued tasks pool, but added in the running tasks pool
    """
    # Get the consumer ID
    consumer_id = req.get_json().get("consumer_id")
    if not is_consumer_id(consumer_id):
        _fail(428, "No valid consumer id")

    # Pop the task from the queue
    task = qapi.get_queue().pop(consumer_id)

    # Return the task info
    task_uid = get_task_uid(task, default="<empty>")
    logger.info("::server.pop: {} [{}]".format(task_uid, consumer_id))
    return get_task_info(task, complete=True)
Example #10
0
    def delete(self, task):
        """Removes a task from the queue. Sends a POST to the queue server and
        removes the task from the local pool of tasks
        :param task: task's unique id (task_uid) or QueueTask object
        """
        task_uid = get_task_uid(task)
        payload = {"task_uid": task_uid}
        try:
            self._post("delete", payload=payload)
        except HTTPError as e:
            # If not found (404), return None instead of exception to make this
            # client utility to behave as server's
            if e.response.status_code != 404:
                raise e

        # Remove from our pool
        self._tasks = filter(lambda t: t.task_uid != task_uid, self._tasks)
Example #11
0
    def timeout(self, task):
        """Notifies the queue that the processing of the task timed out.
        Increases the max_seconds to spend with this task in 1.5 and removes
        the task from the running tasks. If remaining retries, the task is
        eventually re-queued. Is added to the pool of failed otherwise
        :param task: task's unique id (task_uid) or QueueTask object
        """
        with self.__lock:
            # We do this dance because the task passed in is probably a copy,
            # but self._timeout expects a reference to self._tasks
            task_uid = get_task_uid(task)
            task = filter(lambda t: t.task_uid == task_uid, self._tasks)
            if not task:
                raise ValueError("Task is not in the queue")

            # Mark the task as failed by timeout
            self._timeout(task[0])
Example #12
0
    def fail(self, task, error_message=None):
        """Notifies the queue that the processing of the task failed. Removes
        the task from the running tasks. Is re-queued if there are remaining
        retries still. Otherwise, adds the task to the pool of failed
        :param task: task's unique id (task_uid) or QueueTask object
        :param error_message: (Optional) the error/traceback
        """
        with self.__lock:
            # We do this dance because the task passed in is probably a copy,
            # but self._fail expects a reference to self._tasks
            task_uid = get_task_uid(task)
            task = filter(lambda t: t.task_uid == task_uid, self._tasks)
            if not task:
                raise ValueError("Task is not in the queue")

            # Label the task as failed
            self._fail(task[0], error_message=error_message)