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)
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)
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)
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)
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)
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)
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)
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)
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)
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)