Skip to content

Implement rate limit throttling #75

Description

@mdavis-xyz

As I user, I expect the client to handle rate limits for me. i.e. if we're throttled, or about to be throttled, the client should sleep and retry.

Looking at the code, that's not what it currently does.


    def _check_rate_limit(self, time_diff_noauth, time_diff_auth, func):
        """
        Impose client-side rate limit.

        :param int time_diff_noauth: the minimum time between two requests in seconds if not using authentication.
        :param int time_diff_auth: the minimum time between two requests in seconds if using authentication.
        :param callable func: the API function to evaluate.
        :rtype: bool
        """
        if len(self._auth) < 2:
            return abs(time.time() - self._last_requests[func]) >= time_diff_noauth
        else:
            return abs(time.time() - self._last_requests[func]) >= time_diff_auth

and then:

    if not self._check_rate_limit(0, 1, self.get_my_states):
            logger.debug("Blocking request due to rate limit.")
            return None

I'm confused because this is not blocking. time.sleep() is blocking. Returning None is a highly unexpected behavior. What's the motivation for this? How are users supposed to handle this? Why are users supposed to handle this?

I propose:

    def _check_rate_limit(self, time_diff_noauth, time_diff_auth, func):
        """
        Impose client-side rate limit.

        :param int time_diff_noauth: the minimum time between two requests in seconds if not using authentication.
        :param int time_diff_auth: the minimum time between two requests in seconds if using authentication.
        :param callable func: the API function to evaluate.
        :rtype: bool
        """
        time_since_last = time.time() - self._last_requests[func]
        time_between_requests = time_diff_noauth if self._anonymous else time_diff_auth
        return max(time_between_requests - time_since_last, 0)
            

and:

throttle_time = self._check_rate_limit(10, 5, self.get_states)
if throttle_time > 0:
    logger.debug("Blocking request due to rate limit.")
    time.sleep(throttle_time)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions