Connect to the Slack API and run the event handler loop.

        Args:
            connector: A means of connecting to the Slack API. This can be an
                API :obj:`Token`, an :obj:`EnvVar` from which a token can be
                retrieved, or an established :obj:`SlackClient` instance. If
                absent an attempt will be made to use the ``LAYABOUT_TOKEN``
                environment variable.
            interval: The number of seconds to wait between fetching events
                from the Slack API.
            retries: The number of retry attempts to make if a connection to
                Slack is not established or is lost.
            backoff: The strategy used to determine how long to wait between
                retries. Must take as input the number of the current retry and
                output a :obj:`float`. The retry count begins at 1 and
                continues up to ``retries``. If absent a
                `truncated exponential backoff`_ strategy will be used.
            until: The condition used to evaluate whether this method
                terminates. Must take as input a :obj:`list` of :obj:`dict`
                representing Slack RTM API events and return a :obj:`bool`. If
                absent this method will run forever.

        Raises:
            TypeError: If an unsupported connector is given.
            MissingToken: If no API token is available.
            FailedConnection: If connecting to the Slack API fails.

        .. _truncated exponential backoff:
            https://cloud.google.com/storage/docs/exponential-backoff

def run(self, *,
            connector: Union[EnvVar, Token, SlackClient, None] = None,
            interval: float = 0.5, retries: int = 16,
            backoff: Callable[[int], float] = None,
            until: Callable[[List[dict]], bool] = None) -> None:
        """
        Connect to the Slack API and run the event handler loop.

        Args:
            connector: A means of connecting to the Slack API. This can be an
                API :obj:`Token`, an :obj:`EnvVar` from which a token can be
                retrieved, or an established :obj:`SlackClient` instance. If
                absent an attempt will be made to use the ``LAYABOUT_TOKEN``
                environment variable.
            interval: The number of seconds to wait between fetching events
                from the Slack API.
            retries: The number of retry attempts to make if a connection to
                Slack is not established or is lost.
            backoff: The strategy used to determine how long to wait between
                retries. Must take as input the number of the current retry and
                output a :obj:`float`. The retry count begins at 1 and
                continues up to ``retries``. If absent a
                `truncated exponential backoff`_ strategy will be used.
            until: The condition used to evaluate whether this method
                terminates. Must take as input a :obj:`list` of :obj:`dict`
                representing Slack RTM API events and return a :obj:`bool`. If
                absent this method will run forever.

        Raises:
            TypeError: If an unsupported connector is given.
            MissingToken: If no API token is available.
            FailedConnection: If connecting to the Slack API fails.

        .. _truncated exponential backoff:
            https://cloud.google.com/storage/docs/exponential-backoff
        """
        backoff = backoff or _truncated_exponential
        until = until or _forever

        self._ensure_slack(
            connector=connector,
            retries=retries,
            backoff=backoff
        )
        assert self._slack is not None

        while True:
            events = self._slack.fetch_events()

            if not until(events):
                log.debug('Exiting event loop')
                break

            # Handle events!
            for event in events:
                type_ = event.get('type', '')
                for handler in self._handlers[type_] + self._handlers['*']:
                    fn, kwargs = handler
                    fn(self._slack.inner, event, **kwargs)

            # Maybe don't pester the Slack API too much.
            time.sleep(interval)