Beispiel #1
0
    def _process_request(self, request, message):
        """Process request message and reply back."""
        # NOTE(skudriashev): parse broker message first to get the `reply_to`
        # and the `task_uuid` parameters to have possibility to reply back.
        LOG.debug("Start processing request message.")
        try:
            reply_to, task_uuid = self._parse_message(message)
        except ValueError:
            LOG.exception("Failed to parse broker message")
            return
        else:
            # prepare task progress callback
            progress_callback = functools.partial(
                self._on_update_progress, reply_to, task_uuid)
            # prepare reply callback
            reply_callback = functools.partial(
                self._reply, reply_to, task_uuid)

        # parse request to get task name, action and action arguments
        try:
            task_cls, action, action_args = self._parse_request(**request)
            action_args.update(task_uuid=task_uuid,
                               progress_callback=progress_callback)
        except ValueError:
            with misc.capture_failure() as failure:
                LOG.exception("Failed to parse request")
                reply_callback(result=failure.to_dict())
                return

        # get task endpoint
        try:
            endpoint = self._endpoints[task_cls]
        except KeyError:
            with misc.capture_failure() as failure:
                LOG.exception("The '%s' task endpoint does not exist",
                              task_cls)
                reply_callback(result=failure.to_dict())
                return
        else:
            reply_callback(state=pr.RUNNING)

        # perform task action
        try:
            result = getattr(endpoint, action)(**action_args)
        except Exception:
            with misc.capture_failure() as failure:
                LOG.exception("The %s task execution failed", endpoint)
                reply_callback(result=failure.to_dict())
        else:
            if isinstance(result, misc.Failure):
                reply_callback(result=result.to_dict())
            else:
                reply_callback(state=pr.SUCCESS, result=result)
Beispiel #2
0
 def _publish_request(self, request, worker):
     """Publish request to a given topic."""
     LOG.debug(
         "Submitting execution of '%s' to worker '%s' (expecting"
         " response identified by reply_to=%s and"
         " correlation_id=%s) - waited %0.3f seconds to"
         " get published", request, worker, self._uuid, request.uuid,
         timeutils.now() - request.created_on)
     try:
         self._proxy.publish(request,
                             worker.topic,
                             reply_to=self._uuid,
                             correlation_id=request.uuid)
     except Exception:
         with misc.capture_failure() as failure:
             LOG.critical(
                 "Failed to submit '%s' (transitioning it to"
                 " %s)",
                 request,
                 pr.FAILURE,
                 exc_info=True)
             if request.transition_and_log_error(pr.FAILURE, logger=LOG):
                 with self._ongoing_requests_lock:
                     del self._ongoing_requests[request.uuid]
                 request.set_result(failure)
Beispiel #3
0
 def _publish_request(self, request, topic):
     """Publish request to a given topic."""
     try:
         self._proxy.publish(msg=request,
                             routing_key=topic,
                             reply_to=self._uuid,
                             correlation_id=request.uuid)
     except Exception:
         with misc.capture_failure() as failure:
             LOG.exception("Failed to submit the '%s' request.", request)
             del self._requests_cache[request.uuid]
             request.set_result(failure)
Beispiel #4
0
 def _publish_request(self, request, worker):
     """Publish request to a given topic."""
     LOG.debug("Submitting execution of '%s' to worker '%s' (expecting"
               " response identified by reply_to=%s and"
               " correlation_id=%s)", request, worker, self._uuid,
               request.uuid)
     try:
         self._proxy.publish(request, worker.topic,
                             reply_to=self._uuid,
                             correlation_id=request.uuid)
     except Exception:
         with misc.capture_failure() as failure:
             LOG.critical("Failed to submit '%s' (transitioning it to"
                          " %s)", request, pr.FAILURE, exc_info=True)
             if request.transition_and_log_error(pr.FAILURE, logger=LOG):
                 del self._requests_cache[request.uuid]
                 request.set_result(failure)
Beispiel #5
0
 def _publish_request(self, request, topic):
     """Publish request to a given topic."""
     LOG.debug("Submitting execution of '%s' to topic '%s' (expecting"
               " response identified by reply_to=%s and"
               " correlation_id=%s)", request, topic, self._uuid,
               request.uuid)
     try:
         self._proxy.publish(msg=request,
                             routing_key=topic,
                             reply_to=self._uuid,
                             correlation_id=request.uuid)
     except Exception:
         with misc.capture_failure() as failure:
             LOG.critical("Failed to submit '%s' (transitioning it to"
                          " %s)", request, pr.FAILURE, exc_info=True)
             if request.transition_and_log_error(pr.FAILURE, logger=LOG):
                 del self._requests_cache[request.uuid]
                 request.set_result(failure)
Beispiel #6
0
    def _handle_expired_request(request):
        """Handle expired request.

        When request has expired it is removed from the requests cache and
        the `RequestTimeout` exception is set as a request result.
        """
        if request.transition_and_log_error(pr.FAILURE, logger=LOG):
            # Raise an exception (and then catch it) so we get a nice
            # traceback that the request will get instead of it getting
            # just an exception with no traceback...
            try:
                request_age = timeutils.delta_seconds(request.created_on,
                                                      timeutils.utcnow())
                raise exc.RequestTimeout(
                    "Request '%s' has expired after waiting for %0.2f"
                    " seconds for it to transition out of (%s) states" %
                    (request, request_age, ", ".join(pr.WAITING_STATES)))
            except exc.RequestTimeout:
                with misc.capture_failure() as failure:
                    LOG.debug(failure.exception_str)
                    request.set_result(failure)
Beispiel #7
0
    def _handle_expired_request(request):
        """Handle expired request.

        When request has expired it is removed from the requests cache and
        the `RequestTimeout` exception is set as a request result.
        """
        if request.transition_and_log_error(pr.FAILURE, logger=LOG):
            # Raise an exception (and then catch it) so we get a nice
            # traceback that the request will get instead of it getting
            # just an exception with no traceback...
            try:
                request_age = timeutils.delta_seconds(request.created_on,
                                                      timeutils.utcnow())
                raise exc.RequestTimeout(
                    "Request '%s' has expired after waiting for %0.2f"
                    " seconds for it to transition out of (%s) states"
                    % (request, request_age, ", ".join(pr.WAITING_STATES)))
            except exc.RequestTimeout:
                with misc.capture_failure() as failure:
                    LOG.debug(failure.exception_str)
                    request.set_result(failure)
Beispiel #8
0
    def _process_request(self, request, message):
        """Process request message and reply back."""
        try:
            # NOTE(skudriashev): parse broker message first to get
            # the `reply_to` and the `task_uuid` parameters to have
            # possibility to reply back (if we can't parse, we can't respond
            # in the first place...).
            reply_to, task_uuid = self._parse_message(message)
        except ValueError:
            LOG.warn("Failed to parse request attributes from message '%s'",
                     ku.DelayedPretty(message), exc_info=True)
            return
        else:
            # prepare reply callback
            reply_callback = functools.partial(self._reply, True, reply_to,
                                               task_uuid)

        # Parse the request to get the activity/work to perform.
        try:
            work = pr.Request.from_dict(request, task_uuid=task_uuid)
        except ValueError:
            with misc.capture_failure() as failure:
                LOG.warn("Failed to parse request contents from message '%s'",
                         ku.DelayedPretty(message), exc_info=True)
                reply_callback(result=pr.failure_to_dict(failure))
                return

        # Now fetch the task endpoint (and action handler on it).
        try:
            endpoint = self._endpoints[work.task_cls]
        except KeyError:
            with misc.capture_failure() as failure:
                LOG.warn("The '%s' task endpoint does not exist, unable"
                         " to continue processing request message '%s'",
                         work.task_cls, ku.DelayedPretty(message),
                         exc_info=True)
                reply_callback(result=pr.failure_to_dict(failure))
                return
        else:
            try:
                handler = getattr(endpoint, work.action)
            except AttributeError:
                with misc.capture_failure() as failure:
                    LOG.warn("The '%s' handler does not exist on task endpoint"
                             " '%s', unable to continue processing request"
                             " message '%s'", work.action, endpoint,
                             ku.DelayedPretty(message), exc_info=True)
                    reply_callback(result=pr.failure_to_dict(failure))
                    return
            else:
                try:
                    task = endpoint.generate(name=work.task_name)
                except Exception:
                    with misc.capture_failure() as failure:
                        LOG.warn("The '%s' task '%s' generation for request"
                                 " message '%s' failed", endpoint, work.action,
                                 ku.DelayedPretty(message), exc_info=True)
                        reply_callback(result=pr.failure_to_dict(failure))
                        return
                else:
                    if not reply_callback(state=pr.RUNNING):
                        return

        # Associate *any* events this task emits with a proxy that will
        # emit them back to the engine... for handling at the engine side
        # of things...
        if task.notifier.can_be_registered(nt.Notifier.ANY):
            task.notifier.register(nt.Notifier.ANY,
                                   functools.partial(self._on_event,
                                                     reply_to, task_uuid))
        elif isinstance(task.notifier, nt.RestrictedNotifier):
            # Only proxy the allowable events then...
            for event_type in task.notifier.events_iter():
                task.notifier.register(event_type,
                                       functools.partial(self._on_event,
                                                         reply_to, task_uuid))

        # Perform the task action.
        try:
            result = handler(task, **work.arguments)
        except Exception:
            with misc.capture_failure() as failure:
                LOG.warn("The '%s' endpoint '%s' execution for request"
                         " message '%s' failed", endpoint, work.action,
                         ku.DelayedPretty(message), exc_info=True)
                reply_callback(result=pr.failure_to_dict(failure))
        else:
            # And be done with it!
            if isinstance(result, ft.Failure):
                reply_callback(result=result.to_dict())
            else:
                reply_callback(state=pr.SUCCESS, result=result)
Beispiel #9
0
    def _process_request(self, request, message):
        """Process request message and reply back."""
        LOG.debug("Started processing request message %r",
                  message.delivery_tag)
        try:
            # NOTE(skudriashev): parse broker message first to get
            # the `reply_to` and the `task_uuid` parameters to have
            # possibility to reply back (if we can't parse, we can't respond
            # in the first place...).
            reply_to, task_uuid = self._parse_message(message)
        except ValueError:
            LOG.warn("Failed to parse request attributes from message %r",
                     message.delivery_tag,
                     exc_info=True)
            return
        else:
            # prepare task progress callback
            progress_callback = functools.partial(self._on_update_progress,
                                                  reply_to, task_uuid)
            # prepare reply callback
            reply_callback = functools.partial(self._reply, True, reply_to,
                                               task_uuid)

        # parse request to get task name, action and action arguments
        try:
            task_cls, action, action_args = self._parse_request(**request)
            action_args.update(task_uuid=task_uuid,
                               progress_callback=progress_callback)
        except ValueError:
            with misc.capture_failure() as failure:
                LOG.warn("Failed to parse request contents from message %r",
                         message.delivery_tag,
                         exc_info=True)
                reply_callback(result=failure.to_dict())
                return

        # get task endpoint
        try:
            endpoint = self._endpoints[task_cls]
        except KeyError:
            with misc.capture_failure() as failure:
                LOG.warn(
                    "The '%s' task endpoint does not exist, unable"
                    " to continue processing request message %r",
                    task_cls,
                    message.delivery_tag,
                    exc_info=True)
                reply_callback(result=failure.to_dict())
                return
        else:
            try:
                handler = getattr(endpoint, action)
            except AttributeError:
                with misc.capture_failure() as failure:
                    LOG.warn(
                        "The '%s' handler does not exist on task endpoint"
                        " '%s', unable to continue processing request"
                        " message %r",
                        action,
                        endpoint,
                        message.delivery_tag,
                        exc_info=True)
                    reply_callback(result=failure.to_dict())
                    return
            else:
                if not reply_callback(state=pr.RUNNING):
                    return

        # perform task action
        try:
            result = handler(**action_args)
        except Exception:
            with misc.capture_failure() as failure:
                LOG.warn(
                    "The '%s' endpoint '%s' execution for request"
                    " message %r failed",
                    endpoint,
                    action,
                    message.delivery_tag,
                    exc_info=True)
                reply_callback(result=failure.to_dict())
        else:
            if isinstance(result, misc.Failure):
                reply_callback(result=result.to_dict())
            else:
                reply_callback(state=pr.SUCCESS, result=result)
Beispiel #10
0
    def _process_request(self, request, message):
        """Process request message and reply back."""
        LOG.debug("Started processing request message %r",
                  message.delivery_tag)
        try:
            # NOTE(skudriashev): parse broker message first to get
            # the `reply_to` and the `task_uuid` parameters to have
            # possibility to reply back (if we can't parse, we can't respond
            # in the first place...).
            reply_to, task_uuid = self._parse_message(message)
        except ValueError:
            LOG.warn("Failed to parse request attributes from message %r",
                     message.delivery_tag, exc_info=True)
            return
        else:
            # prepare task progress callback
            progress_callback = functools.partial(self._on_update_progress,
                                                  reply_to, task_uuid)
            # prepare reply callback
            reply_callback = functools.partial(self._reply, True, reply_to,
                                               task_uuid)

        # parse request to get task name, action and action arguments
        try:
            task_cls, action, action_args = self._parse_request(**request)
            action_args.update(task_uuid=task_uuid,
                               progress_callback=progress_callback)
        except ValueError:
            with misc.capture_failure() as failure:
                LOG.warn("Failed to parse request contents from message %r",
                         message.delivery_tag, exc_info=True)
                reply_callback(result=failure.to_dict())
                return

        # get task endpoint
        try:
            endpoint = self._endpoints[task_cls]
        except KeyError:
            with misc.capture_failure() as failure:
                LOG.warn("The '%s' task endpoint does not exist, unable"
                         " to continue processing request message %r",
                         task_cls, message.delivery_tag, exc_info=True)
                reply_callback(result=failure.to_dict())
                return
        else:
            try:
                handler = getattr(endpoint, action)
            except AttributeError:
                with misc.capture_failure() as failure:
                    LOG.warn("The '%s' handler does not exist on task endpoint"
                             " '%s', unable to continue processing request"
                             " message %r", action, endpoint,
                             message.delivery_tag, exc_info=True)
                    reply_callback(result=failure.to_dict())
                    return
            else:
                if not reply_callback(state=pr.RUNNING):
                    return

        # perform task action
        try:
            result = handler(**action_args)
        except Exception:
            with misc.capture_failure() as failure:
                LOG.warn("The '%s' endpoint '%s' execution for request"
                         " message %r failed", endpoint, action,
                         message.delivery_tag, exc_info=True)
                reply_callback(result=failure.to_dict())
        else:
            if isinstance(result, ft.Failure):
                reply_callback(result=result.to_dict())
            else:
                reply_callback(state=pr.SUCCESS, result=result)
Beispiel #11
0
    def _process_request(self, request, message):
        """Process request message and reply back."""
        LOG.debug("Started processing request message '%s'",
                  ku.DelayedPretty(message))
        try:
            # NOTE(skudriashev): parse broker message first to get
            # the `reply_to` and the `task_uuid` parameters to have
            # possibility to reply back (if we can't parse, we can't respond
            # in the first place...).
            reply_to, task_uuid = self._parse_message(message)
        except ValueError:
            LOG.warn("Failed to parse request attributes from message '%s'",
                     ku.DelayedPretty(message),
                     exc_info=True)
            return
        else:
            # prepare reply callback
            reply_callback = functools.partial(self._reply, True, reply_to,
                                               task_uuid)

        # parse request to get task name, action and action arguments
        try:
            bundle = self._parse_request(**request)
            task_cls, task_name, action, arguments = bundle
            arguments['task_uuid'] = task_uuid
        except ValueError:
            with misc.capture_failure() as failure:
                LOG.warn("Failed to parse request contents from message '%s'",
                         ku.DelayedPretty(message),
                         exc_info=True)
                reply_callback(result=failure.to_dict())
                return

        # get task endpoint
        try:
            endpoint = self._endpoints[task_cls]
        except KeyError:
            with misc.capture_failure() as failure:
                LOG.warn(
                    "The '%s' task endpoint does not exist, unable"
                    " to continue processing request message '%s'",
                    task_cls,
                    ku.DelayedPretty(message),
                    exc_info=True)
                reply_callback(result=failure.to_dict())
                return
        else:
            try:
                handler = getattr(endpoint, action)
            except AttributeError:
                with misc.capture_failure() as failure:
                    LOG.warn(
                        "The '%s' handler does not exist on task endpoint"
                        " '%s', unable to continue processing request"
                        " message '%s'",
                        action,
                        endpoint,
                        ku.DelayedPretty(message),
                        exc_info=True)
                    reply_callback(result=failure.to_dict())
                    return
            else:
                try:
                    task = endpoint.generate(name=task_name)
                except Exception:
                    with misc.capture_failure() as failure:
                        LOG.warn(
                            "The '%s' task '%s' generation for request"
                            " message '%s' failed",
                            endpoint,
                            action,
                            ku.DelayedPretty(message),
                            exc_info=True)
                        reply_callback(result=failure.to_dict())
                        return
                else:
                    if not reply_callback(state=pr.RUNNING):
                        return

        # associate *any* events this task emits with a proxy that will
        # emit them back to the engine... for handling at the engine side
        # of things...
        if task.notifier.can_be_registered(nt.Notifier.ANY):
            task.notifier.register(
                nt.Notifier.ANY,
                functools.partial(self._on_event, reply_to, task_uuid))
        elif isinstance(task.notifier, nt.RestrictedNotifier):
            # only proxy the allowable events then...
            for event_type in task.notifier.events_iter():
                task.notifier.register(
                    event_type,
                    functools.partial(self._on_event, reply_to, task_uuid))

        # perform the task action
        try:
            result = handler(task, **arguments)
        except Exception:
            with misc.capture_failure() as failure:
                LOG.warn(
                    "The '%s' endpoint '%s' execution for request"
                    " message '%s' failed",
                    endpoint,
                    action,
                    ku.DelayedPretty(message),
                    exc_info=True)
                reply_callback(result=failure.to_dict())
        else:
            if isinstance(result, ft.Failure):
                reply_callback(result=result.to_dict())
            else:
                reply_callback(state=pr.SUCCESS, result=result)