semaphores

This commit is contained in:
Erica Z 2024-11-15 10:25:10 +01:00
parent 9bad158f91
commit 118e82d432

View file

@ -6,6 +6,8 @@ pub use album_list::AlbumListType;
use adw::glib; use adw::glib;
use bytes::Bytes; use bytes::Bytes;
use rand::Rng; use rand::Rng;
use std::sync::Arc;
use tokio::sync::Semaphore;
use tracing::{event, Level}; use tracing::{event, Level};
fn runtime() -> &'static tokio::runtime::Runtime { fn runtime() -> &'static tokio::runtime::Runtime {
@ -56,6 +58,7 @@ impl From<reqwest::Error> for Error {
pub struct Client { pub struct Client {
client: reqwest::Client, client: reqwest::Client,
base_url: reqwest::Url, base_url: reqwest::Url,
sem: Arc<Semaphore>,
} }
fn random_salt(length: usize) -> String { fn random_salt(length: usize) -> String {
@ -106,6 +109,7 @@ impl Client {
.user_agent(crate::USER_AGENT) .user_agent(crate::USER_AGENT)
.build()?, .build()?,
base_url, base_url,
sem: Arc::new(Semaphore::new(20)), // 20 requests at one time
}) })
} }
@ -121,7 +125,10 @@ impl Client {
// note that this is why those silly bounds on T are needed, because we're // note that this is why those silly bounds on T are needed, because we're
// sending back the result of the query from another thread // sending back the result of the query from another thread
let future = request.send(); let future = request.send();
let sem = Arc::clone(&self.sem);
runtime().spawn(async move { runtime().spawn(async move {
let _permit = sem.acquire().await.unwrap();
// wrap this logic in a fn so we can use ? // wrap this logic in a fn so we can use ?
async fn perform<T: serde::de::DeserializeOwned + Send + 'static>( async fn perform<T: serde::de::DeserializeOwned + Send + 'static>(
response: Result<reqwest::Response, reqwest::Error>, response: Result<reqwest::Response, reqwest::Error>,
@ -195,7 +202,10 @@ impl Client {
let (sender, receiver) = async_channel::bounded(1); let (sender, receiver) = async_channel::bounded(1);
let future = self.client.get(self.cover_art_url(id, size)).send(); let future = self.client.get(self.cover_art_url(id, size)).send();
let sem = Arc::clone(&self.sem);
runtime().spawn(async move { runtime().spawn(async move {
let _permit = sem.acquire().await.unwrap();
async fn perform( async fn perform(
response: Result<reqwest::Response, reqwest::Error>, response: Result<reqwest::Response, reqwest::Error>,
) -> Result<Bytes, Error> { ) -> Result<Bytes, Error> {