use std::time;
use leaky_bucket::RateLimiter;
use crate::{Client, Error, InvoiceAction, Result, Search, SearchResult};
pub struct RateLimitedClient {
pub c: Client,
search_rl: RateLimiter,
get_invoice_rl: RateLimiter,
}
impl RateLimitedClient {
pub fn new(c: Client) -> Self {
let search_rl = RateLimiter::builder()
.initial(1)
.max(1)
.refill(1)
.interval(tokio::time::Duration::from_millis(1100)) .build();
let get_invoice_rl = RateLimiter::builder()
.initial(10)
.max(10)
.refill(10)
.interval(tokio::time::Duration::from_millis(1100)) .build();
Self {
c,
search_rl,
get_invoice_rl,
}
}
pub async fn search(&self, search_args: &Search) -> Result<SearchResult> {
loop {
self.search_rl.acquire(1).await;
match crate::search::search_for_actions(search_args)
.send(&self.c)
.await
{
Ok(res) => return Ok(res),
Err(Error::RateLimited) => {
println!("Rate limited, sleeping for 1 second");
tokio::time::sleep(time::Duration::from_secs(1)).await;
}
Err(err) => return Err(err),
};
}
}
pub async fn get_invoice(&self, id: &str) -> Result<InvoiceAction> {
loop {
self.get_invoice_rl.acquire(1).await;
match crate::invoice::get_an_invoice(id).send(&self.c).await {
Ok(res) => return Ok(res),
Err(Error::RateLimited) => {
println!("Rate limited, sleeping for 1 second");
tokio::time::sleep(time::Duration::from_secs(1)).await;
}
Err(err) => return Err(err),
};
}
}
}