cordon off the tokio runtime to the subsonic client

This commit is contained in:
Erica Z 2024-11-01 09:58:03 +01:00
parent abd2331eb2
commit 9f97a2cae3
2 changed files with 24 additions and 13 deletions

View file

@ -30,13 +30,6 @@ pub mod mpv;
#[link(name = "soup-3.0")] #[link(name = "soup-3.0")]
extern "C" {} extern "C" {}
pub fn runtime() -> &'static tokio::runtime::Runtime {
static RUNTIME: std::sync::OnceLock<tokio::runtime::Runtime> = std::sync::OnceLock::new();
RUNTIME.get_or_init(|| {
tokio::runtime::Runtime::new().expect("could not initialize the tokio runtime")
})
}
fn main() -> glib::ExitCode { fn main() -> glib::ExitCode {
gio::resources_register_include!("audrey.gresource").expect("could not register resources"); gio::resources_register_include!("audrey.gresource").expect("could not register resources");
@ -52,7 +45,7 @@ fn main() -> glib::ExitCode {
let app = Application::new(); let app = Application::new();
// smol test for the subsonic client // smol test for the subsonic client
runtime().spawn(async { glib::spawn_future_local(async {
let keyring = oo7::Keyring::new().await.unwrap(); let keyring = oo7::Keyring::new().await.unwrap();
let attributes = vec![("xdg:schema", APP_ID)]; let attributes = vec![("xdg:schema", APP_ID)];
let items = keyring.search_items(&attributes).await.unwrap(); let items = keyring.search_items(&attributes).await.unwrap();

View file

@ -1,5 +1,12 @@
mod schema; mod schema;
fn runtime() -> &'static tokio::runtime::Runtime {
static RUNTIME: std::sync::OnceLock<tokio::runtime::Runtime> = std::sync::OnceLock::new();
RUNTIME.get_or_init(|| {
tokio::runtime::Runtime::new().expect("could not initialize the tokio runtime")
})
}
impl<T> schema::SubsonicResponse<T> { impl<T> schema::SubsonicResponse<T> {
fn fixup(self) -> Result<T, Error> { fn fixup(self) -> Result<T, Error> {
match self { match self {
@ -100,11 +107,22 @@ impl Client {
.unwrap_or_else(|_| unsafe { std::hint::unreachable_unchecked() }) .unwrap_or_else(|_| unsafe { std::hint::unreachable_unchecked() })
.extend(path); .extend(path);
self.client // FIXME: is an entire channel per request overkill? maybe pool them?
.get(url) let (sender, receiver) = async_channel::bounded(1);
.query(query)
.send() let future = self.client.get(url).query(query).send();
.await? runtime().spawn(async move {
let response = future.await;
sender
.send(response)
.await
.expect("could not send subsonic response back to the main loop");
});
receiver
.recv()
.await
.expect("could not receive subsonic response from tokio")?
.error_for_status()? .error_for_status()?
.json::<schema::SubsonicResponseOuter<T>>() .json::<schema::SubsonicResponseOuter<T>>()
.await? .await?