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

Allow manually refilling a RateLimiter #17

Open
raftario opened this issue Jun 9, 2023 · 5 comments
Open

Allow manually refilling a RateLimiter #17

raftario opened this issue Jun 9, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@raftario
Copy link

raftario commented Jun 9, 2023

For scenarios where a task may preemptively acquire more tokens than it ends up requiring and wants to make its unused ones available

@udoprog udoprog added the enhancement New feature or request label Jun 9, 2023
@udoprog
Copy link
Owner

udoprog commented Jun 9, 2023

We currently release tokens once an acquire future is dropped, so in a way this is already implemented but perhaps not to the way you want it.

Do you have an representative code example of what you'd want it to look like?

@raftario
Copy link
Author

raftario commented Jun 9, 2023

Something like this

// Operation could use up to 32 tokens
limiter.acquire(32).await;
// Future polled to completion
// Operation performed but ended only using 24 tokens
limiter.release(8);

@udoprog
Copy link
Owner

udoprog commented Jun 10, 2023

Ah, so you're just looking for a way to manually add permits to the rate limiter?

That's should be fairly easy to implement. It's essentially what the core task does. So we just need to borrow it ;)

@jamesmunns
Copy link

Noting that I could probably use this too, if I have a chance I might look at implementing this.

I have a use case where we need to get tokens for all matching rules (each with separate buckets), and if we get tokens from A and B, but C fails or times out, we could "give back" the acquired A and B tokens as they were unused.

@raftario
Copy link
Author

raftario commented Sep 4, 2024

I don't know whether this is something you'd want in this crate since it could be implemented on top of a simple method thay fills the bucket but a nice additional API for this could look something like this. Given how common the pattern of racing futures and dropping whichever ones don't win this could be really nice to have.

fn reserve(&self, permits: usize) -> impl Future<Reservation>;

impl Reservation {
  fn consume(&mut self, permits: usize) {
    self.used += permits;
  }
}

impl Drop for Reservation {
  fn drop(&mut self) {
    self.limiter.release(self.reserved - self.used);
  }
}

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

No branches or pull requests

3 participants