Fix: update token in blocking task

* attempt to fix https://github.com/hrkfdn/ncspot/issues/1358

mpris runs inside `tokio::runtime.spawn`. At some point it hits `metadata_changed->WebApi::track->api_with_retry`, which gets 401 response and tries to update the token.

This goes into `update_token`, which at a certain point calls *blocking* `token_rx.recv()`. Tokio runtime is not happy about that, as it uses the same thread for the `run_loop` in the worker. That's why `tokio::select!` doesn't work, we're essentially deadlocking, so the worker never pick up `RequestToken` command and `update_token` block forever.

Here I'm changing `update_token` to wrap `recv` in `spawn_blocking`, which makes `update_token` return a `JoinHandle`, on which the caller has to await. This doesn't work nicely in case of mpris though, as it is not an async function, and I don't know how to make it async as it goes through the dbus `metadata_changed` interface. My best effort here is to do `and_then`, which seems to work, but I'm not confident that's the right approach.

* fmt

* move token_rx.recv inside spawn_blocking
This commit is contained in:
Konstantin Sobolev
2024-02-17 03:59:23 -08:00
committed by GitHub
parent 7dec5a2767
commit 5c71e2f4bf
3 changed files with 35 additions and 20 deletions

View File

@@ -83,7 +83,11 @@ impl Spotify {
spotify.set_volume(volume);
spotify.api.set_worker_channel(spotify.channel.clone());
spotify.api.update_token();
ASYNC_RUNTIME
.get()
.unwrap()
.block_on(spotify.api.update_token().unwrap())
.ok();
spotify.api.set_user(user);