示例#1
0
    def _publish_and_raises_on_missing_exchange(self, exchange, msg,
                                                routing_key=None,
                                                timeout=None):
        """Publisher that raises exception if exchange is missing."""
        if not exchange.passive:
            raise RuntimeError("_publish_and_retry_on_missing_exchange() must "
                               "be called with an passive exchange.")

        try:
            self._publish(exchange, msg, routing_key=routing_key,
                          timeout=timeout)
            return
        except self.connection.channel_errors as exc:
            if exc.code == 404:
                # NOTE(noelbk/sileht):
                # If rabbit dies, the consumer can be disconnected before the
                # publisher sends, and if the consumer hasn't declared the
                # queue, the publisher's will send a message to an exchange
                # that's not bound to a queue, and the message wll be lost.
                # So we set passive=True to the publisher exchange and catch
                # the 404 kombu ChannelError and retry until the exchange
                # appears
                raise rpc_amqp.AMQPDestinationNotFound(
                    "exchange %s doesn't exists" % exchange.name)
            raise
示例#2
0
    def _publish_and_retry_on_missing_exchange(self,
                                               exchange,
                                               msg,
                                               routing_key=None,
                                               timeout=None):
        """Publisher that retry if the exchange is missing.
        """

        if not exchange.passive:
            raise RuntimeError("_publish_and_retry_on_missing_exchange() must "
                               "be called with an passive exchange.")

        # TODO(sileht): use @retrying
        # NOTE(sileht): no need to wait the application expect a response
        # before timeout is exshauted
        duration = (timeout
                    if timeout is not None else self.kombu_reconnect_timeout)

        timer = rpc_common.DecayingTimer(duration=duration)
        timer.start()

        while True:
            try:
                self._publish(exchange,
                              msg,
                              routing_key=routing_key,
                              timeout=timeout)
                return
            except self.connection.channel_errors as exc:
                # NOTE(noelbk/sileht):
                # If rabbit dies, the consumer can be disconnected before the
                # publisher sends, and if the consumer hasn't declared the
                # queue, the publisher's will send a message to an exchange
                # that's not bound to a queue, and the message wll be lost.
                # So we set passive=True to the publisher exchange and catch
                # the 404 kombu ChannelError and retry until the exchange
                # appears
                if exc.code == 404 and timer.check_return() > 0:
                    LOG.info(
                        _LI("The exchange %(exchange)s to send to "
                            "%(routing_key)s doesn't exist yet, "
                            "retrying...") % {
                                'exchange': exchange.name,
                                'routing_key': routing_key
                            })
                    time.sleep(0.25)
                    continue
                elif exc.code == 404:
                    msg = _("The exchange %(exchange)s to send to "
                            "%(routing_key)s still doesn't exist after "
                            "%(duration)s sec abandoning...") % {
                                'duration': duration,
                                'exchange': exchange.name,
                                'routing_key': routing_key
                            }
                    LOG.info(msg)
                    raise rpc_amqp.AMQPDestinationNotFound(msg)
                raise