Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rate limiting and export progress tracking #75

Merged
merged 3 commits into from
Nov 16, 2020

Conversation

watsonbox
Copy link
Owner

This PR is in two parts: the rate limiting itself, and the progress UI.

Rate Limiting

On the rate limiting topic, I reviewed the discussion here and the proposal here. The problem with a throttling approach, as mentioned, is that two users with independently throttled requests can still encounter rate limiting due to the combined throughput. Additionally, it seems to me that we're also required to take a guess as to what level of throttling is acceptable (for example 10 requests per second), but since I can't find it in the documentation there's presumably no guarantee that this won't change either temporarily or permanently on their side.

The approach I've taken here is the one described in their documentation:

If Web API returns status code 429, it means that you have sent too many requests. When this happens, check the Retry-After header, where you will see a number displayed. This is the number of seconds that you need to wait, before you try your request again.

This way, it's the server itself that tells each client how long to wait, and so it should work fine across multiple users and is also resistant to any change in logic on Spotify's side. Furthermore, we can run requests as fast as we like until the server tells us otherwise, which should hopefully result in the fastest possible export times.

If we do want to add basic throttling at any point, I've added the bottleneck job scheduler and rate limiter which can be simply and transparently configured to allow this. I've tried to isolate the rate limiting as much as possible from the app logic itself since it's really an implementation detail.

Progress UI

The other part of this feature, which I'd wanted to add sooner, is a clearer indication of how long the export will take.

Here's how it looks:

progress_screen_capture

I did think about adding some indication to the UI that the export was paused due to a rate limiting delay, but decided not to because I want to keep the interface as simple as possible, and:

  1. The progress bar is animated when it's still running, showing visually that things are still happening.
  2. In my admittedly limited testing, the delays requested from the server tended to be ~10s max, which doesn't feel too long in the context of a large export.

@watsonbox watsonbox self-assigned this Nov 12, 2020
@watsonbox watsonbox mentioned this pull request Nov 12, 2020
window.location.href = window.location.href.split('#')[0]
} else if (error.status === 429 && jobInfo.retryCount === 0) {
// Retry according to the indication from the server with a small buffer
return ((error.getResponseHeader("Retry-After") || 1) * 1000) + 1000
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth making this a random buffer 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant