Skip to content

Commit 2c12099

Browse files
authored
Optimize CLI command runtime (#249)
Resolves #248 - optimized runtime for `get key playback` CLI command - optimized runtime for `playback` CLI commands
1 parent 24049c7 commit 2c12099

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

spotify_player/src/cli/client.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ async fn handle_socket_request(
8989
}
9090

9191
match request {
92-
Request::Get(GetRequest::Key(key)) => handle_get_key_request(client, key).await,
92+
Request::Get(GetRequest::Key(key)) => handle_get_key_request(client, state, key).await,
9393
Request::Get(GetRequest::Item(item_type, id_or_name)) => {
9494
handle_get_item_request(client, item_type, id_or_name).await
9595
}
@@ -145,13 +145,10 @@ async fn handle_socket_request(
145145
}
146146
}
147147

148-
async fn handle_get_key_request(client: &Client, key: Key) -> Result<Vec<u8>> {
148+
async fn handle_get_key_request(client: &Client, state: &SharedState, key: Key) -> Result<Vec<u8>> {
149149
Ok(match key {
150150
Key::Playback => {
151-
let playback = client
152-
.spotify
153-
.current_playback(None, None::<Vec<_>>)
154-
.await?;
151+
let playback = state.player.read().current_playback();
155152
serde_json::to_vec(&playback)?
156153
}
157154
Key::Devices => {
@@ -357,8 +354,22 @@ async fn handle_playback_request(
357354
}
358355
};
359356

360-
client.handle_player_request(state, player_request).await?;
361-
client.update_playback(state);
357+
tokio::task::spawn({
358+
let client = client.clone();
359+
let state = state.clone();
360+
async move {
361+
match client.handle_player_request(&state, player_request).await {
362+
Ok(()) => {
363+
client.update_playback(&state);
364+
}
365+
Err(err) => {
366+
tracing::warn!(
367+
"Failed to handle a player request for playback CLI command: {err:#}"
368+
);
369+
}
370+
}
371+
}
372+
});
362373
Ok(())
363374
}
364375

spotify_player/src/state/player.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,37 @@ pub struct PlayerState {
1515
}
1616

1717
impl PlayerState {
18+
/// gets the current playback state
19+
///
20+
/// # Note
21+
/// Because playback data stored inside the player state is buffered and cached,
22+
/// this function tries to estimate the current playback based on the available state data.
23+
pub fn current_playback(&self) -> Option<rspotify_model::CurrentPlaybackContext> {
24+
let mut playback = self.playback.clone()?;
25+
26+
// update the playback's progress based on the `playback_last_updated_time`
27+
playback.progress = playback.progress.map(|d| {
28+
d + if playback.is_playing {
29+
chrono::Duration::from_std(self.playback_last_updated_time.unwrap().elapsed())
30+
.unwrap()
31+
} else {
32+
chrono::Duration::zero()
33+
}
34+
});
35+
36+
// update the playback's metadata based on the `buffered_playback` metadata
37+
if let Some(ref p) = self.buffered_playback {
38+
playback.device.name = p.device_name.clone();
39+
playback.device.id = p.device_id.clone();
40+
playback.is_playing = p.is_playing;
41+
playback.device.volume_percent = p.volume;
42+
playback.repeat_state = p.repeat_state;
43+
playback.shuffle_state = p.shuffle_state;
44+
}
45+
46+
Some(playback)
47+
}
48+
1849
/// gets the current playing track
1950
pub fn current_playing_track(&self) -> Option<&rspotify_model::FullTrack> {
2051
match self.playback {

0 commit comments

Comments
 (0)