1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-07-01 10:41:03 +02:00

fix(mpd): stops working if connection lost

The client will now attempt to reconnect when a connection loss is detected.

Fixes #21.
This commit is contained in:
Jake Stanger 2023-01-28 14:40:12 +00:00
parent 1cdfebf8db
commit 90cd078973
No known key found for this signature in database
GPG key ID: C51FC8F9CB0BEA61
4 changed files with 67 additions and 25 deletions

View file

@ -7,7 +7,11 @@ use tokio::sync::broadcast;
pub mod mpd; pub mod mpd;
pub mod mpris; pub mod mpris;
pub type PlayerUpdate = (Option<Track>, Status); #[derive(Clone, Debug)]
pub enum PlayerUpdate {
Update(Box<Option<Track>>, Status),
Disconnect,
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Track { pub struct Track {

View file

@ -19,7 +19,7 @@ use tokio::spawn;
use tokio::sync::broadcast::{channel, error::SendError, Receiver, Sender}; use tokio::sync::broadcast::{channel, error::SendError, Receiver, Sender};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tokio::time::sleep; use tokio::time::sleep;
use tracing::{debug, error}; use tracing::{debug, error, info};
lazy_static! { lazy_static! {
static ref CONNECTIONS: Arc<Mutex<HashMap<String, Arc<MpdClient>>>> = static ref CONNECTIONS: Arc<Mutex<HashMap<String, Arc<MpdClient>>>> =
@ -72,7 +72,9 @@ impl MpdClient {
Subsystem::Player | Subsystem::Queue | Subsystem::Mixer, Subsystem::Player | Subsystem::Queue | Subsystem::Mixer,
) = change ) = change
{ {
Self::send_update(&client, &tx, &music_dir).await?; Self::send_update(&client, &tx, &music_dir)
.await
.expect("Failed to send update");
} }
} }
@ -92,7 +94,7 @@ impl MpdClient {
client: &Client, client: &Client,
tx: &Sender<PlayerUpdate>, tx: &Sender<PlayerUpdate>,
music_dir: &Path, music_dir: &Path,
) -> Result<(), SendError<(Option<Track>, Status)>> { ) -> Result<(), SendError<PlayerUpdate>> {
let current_song = client.command(commands::CurrentSong).await; let current_song = client.command(commands::CurrentSong).await;
let status = client.command(commands::Status).await; let status = client.command(commands::Status).await;
@ -100,12 +102,22 @@ impl MpdClient {
let track = current_song.map(|s| Self::convert_song(&s.song, music_dir)); let track = current_song.map(|s| Self::convert_song(&s.song, music_dir));
let status = Status::from(status); let status = Status::from(status);
tx.send((track, status))?; tx.send(PlayerUpdate::Update(Box::new(track), status))?;
} }
Ok(()) Ok(())
} }
fn is_connected(&self) -> bool {
!self.client.is_connection_closed()
}
fn send_disconnect_update(&self) -> Result<(), SendError<PlayerUpdate>> {
info!("Connection to MPD server lost");
self.tx.send(PlayerUpdate::Disconnect)?;
Ok(())
}
fn convert_song(song: &Song, music_dir: &Path) -> Track { fn convert_song(song: &Song, music_dir: &Path) -> Track {
let (track, disc) = song.number(); let (track, disc) = song.number();
@ -189,7 +201,20 @@ pub async fn get_client(
connections.insert(host.to_string(), Arc::clone(&client)); connections.insert(host.to_string(), Arc::clone(&client));
Ok(client) Ok(client)
} }
Some(client) => Ok(Arc::clone(client)), Some(client) => {
if client.is_connected() {
Ok(Arc::clone(client))
} else {
client
.send_disconnect_update()
.expect("Failed to send disconnect update");
let client = MpdClient::new(host, music_dir).await?;
let client = Arc::new(client);
connections.insert(host.to_string(), Arc::clone(&client));
Ok(client)
}
}
} }
} }

View file

@ -170,7 +170,7 @@ impl Client {
let track = Track::from(metadata); let track = Track::from(metadata);
let player_update: PlayerUpdate = (Some(track), status); let player_update = PlayerUpdate::Update(Box::new(Some(track)), status);
tx.send(player_update) tx.send(player_update)
.expect("Failed to send player update"); .expect("Failed to send player update");

View file

@ -178,30 +178,43 @@ impl Module<Button> for MusicModule {
let music_dir = self.music_dir.clone(); let music_dir = self.music_dir.clone();
spawn(async move { spawn(async move {
let mut rx = { loop {
let client = get_client(player_type, &host, music_dir).await; let mut rx = {
client.subscribe_change() let client = get_client(player_type, &host, music_dir.clone()).await;
}; client.subscribe_change()
};
while let Ok((track, status)) = rx.recv().await { while let Ok(update) = rx.recv().await {
match track { match update {
Some(track) => { PlayerUpdate::Update(track, status) => match *track {
let display_string = Some(track) => {
replace_tokens(format.as_str(), &tokens, &track, &status, &icons); let display_string = replace_tokens(
format.as_str(),
&tokens,
&track,
&status,
&icons,
);
let update = SongUpdate { let update = SongUpdate {
song: track, song: track,
status, status,
display_string, display_string,
}; };
tx.send(ModuleUpdateEvent::Update(Some(update))).await?; tx.send(ModuleUpdateEvent::Update(Some(update)))
.await
.expect(ERR_CHANNEL_SEND);
}
None => tx
.send(ModuleUpdateEvent::Update(None))
.await
.expect(ERR_CHANNEL_SEND),
},
PlayerUpdate::Disconnect => break,
} }
None => tx.send(ModuleUpdateEvent::Update(None)).await?,
} }
} }
Ok::<(), mpsc::error::SendError<ModuleUpdateEvent<Self::SendMessage>>>(())
}); });
} }