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:
parent
1cdfebf8db
commit
90cd078973
4 changed files with 67 additions and 25 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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>>>(())
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue