def run(self, connection, wrapped_callback):
        """
        Run the wrapped_callback in a protective covering of retries and error handling.

        :param connection: Connection to messaging service
        :type connection: kombu.connection.Connection

        :param wrapped_callback: Callback that will be wrapped by all the fine handling in this
                                 method. Expected signature of callback -
                                 ``def func(connection, channel)``
        """
        should_stop = False
        channel = None
        while not should_stop:
            try:
                channel = connection.channel()
                wrapped_callback(connection=connection, channel=channel)
                should_stop = True
            except connection.connection_errors + connection.channel_errors as e:
                should_stop, wait = self._retry_context.test_should_stop(e)
                # reset channel to None to avoid any channel closing errors. At this point
                # in case of an exception there should be no channel but that is better to
                # guarantee.
                channel = None
                # All attempts to re-establish connections have failed. This error needs to
                # be notified so raise.
                if should_stop:
                    raise

                # -1, 0 and 1+ are handled properly by eventlet.sleep
                self._logger.debug(
                    "Received RabbitMQ server error, sleeping for %s seconds "
                    "before retrying: %s" % (wait, six.text_type(e))
                )
                concurrency.sleep(wait)

                connection.close()
                # ensure_connection will automatically switch to an alternate. Other connections
                # in the pool will be fixed independently. It would be nice to cut-over the
                # entire ConnectionPool simultaneously but that would require writing our own
                # ConnectionPool. If a server recovers it could happen that the same process
                # ends up talking to separate nodes in a cluster.

                def log_error_on_conn_failure(exc, interval):
                    self._logger.debug(
                        "Failed to re-establish connection to RabbitMQ server, "
                        "retrying in %s seconds: %s" % (interval, six.text_type(exc))
                    )

                try:
                    # NOTE: This function blocks and tries to restablish a connection for
                    # indefinetly if "max_retries" argument is not specified
                    connection.ensure_connection(
                        max_retries=self._ensure_max_retries,
                        errback=log_error_on_conn_failure,
                    )
                except Exception:
                    self._logger.exception(
                        "Connections to RabbitMQ cannot be re-established: %s",
                        six.text_type(e),
                    )
                    raise
            except Exception as e:
                self._logger.exception(
                    "Connections to RabbitMQ cannot be re-established: %s",
                    six.text_type(e),
                )
                # Not being able to publish a message could be a significant issue for an app.
                raise
            finally:
                if should_stop and channel:
                    try:
                        channel.close()
                    except Exception:
                        self._logger.warning("Error closing channel.", exc_info=True)

        Run the wrapped_callback in a protective covering of retries and error handling.

        :param connection: Connection to messaging service
        :type connection: kombu.connection.Connection

        :param wrapped_callback: Callback that will be wrapped by all the fine handling in this
                                 method. Expected signature of callback -
                                 ``def func(connection, channel)``
        
st2common/st2common/transport/connection_retry_wrapper.py