Daemonize the musicbrainz thread #217
@ -1,33 +1,18 @@
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
sync::{
|
||||
mpsc::{self, TryRecvError},
|
||||
Arc, Mutex,
|
||||
},
|
||||
thread, time,
|
||||
};
|
||||
use std::{collections::VecDeque, sync::mpsc::{self, TryRecvError}};
|
||||
|
||||
use musichoard::collection::{
|
||||
album::AlbumMeta,
|
||||
artist::{Artist, ArtistMeta},
|
||||
musicbrainz::{IMusicBrainzRef, Mbid},
|
||||
};
|
||||
use musichoard::collection::{artist::Artist, musicbrainz::IMusicBrainzRef};
|
||||
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{match_state::MatchState, App, AppInner, AppMachine},
|
||||
AppPublicState, AppState, IAppEventFetch, IAppInteractFetch, MatchStateInfo,
|
||||
},
|
||||
event::{Event, EventSender},
|
||||
lib::{
|
||||
external::musicbrainz::daemon::{
|
||||
ApiParams, Job, JobInstance, JobPriority, ReturnSender, SearchArtistParams,
|
||||
SearchParams, SearchReleaseGroupParams,
|
||||
},
|
||||
interface::musicbrainz::{
|
||||
self,
|
||||
api::{Error as MbError, IMusicBrainz},
|
||||
},
|
||||
interface::musicbrainz::api::Error as MbError,
|
||||
},
|
||||
};
|
||||
|
||||
@ -43,7 +28,6 @@ impl FetchState {
|
||||
|
||||
pub type FetchError = MbError;
|
||||
pub type FetchResult = Result<MatchStateInfo, FetchError>;
|
||||
pub type FetchSender = mpsc::Sender<FetchResult>;
|
||||
pub type FetchReceiver = mpsc::Receiver<FetchResult>;
|
||||
|
||||
impl AppMachine<FetchState> {
|
||||
@ -115,58 +99,6 @@ impl AppMachine<FetchState> {
|
||||
let job = Job::new(JobPriority::Background, JobInstance::new(tx, queue));
|
||||
inner.musicbrainz.send(job);
|
||||
}
|
||||
|
||||
fn fetch_artist(
|
||||
musicbrainz: Arc<Mutex<dyn IMusicBrainz + Send>>,
|
||||
fetch_tx: FetchSender,
|
||||
events: EventSender,
|
||||
artist: ArtistMeta,
|
||||
) {
|
||||
let result = musicbrainz.lock().unwrap().search_artist(&artist);
|
||||
let result = result.map(|list| MatchStateInfo::artist(artist, list));
|
||||
Self::send_fetch_result(&fetch_tx, &events, result).ok();
|
||||
}
|
||||
|
||||
fn fetch_albums(
|
||||
musicbrainz: Arc<Mutex<dyn IMusicBrainz + Send>>,
|
||||
fetch_tx: FetchSender,
|
||||
events: EventSender,
|
||||
arid: Mbid,
|
||||
albums: Vec<AlbumMeta>,
|
||||
) {
|
||||
let mut musicbrainz = musicbrainz.lock().unwrap();
|
||||
let mut album_iter = albums.into_iter().peekable();
|
||||
while let Some(album) = album_iter.next() {
|
||||
if album.musicbrainz.is_some() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let result = musicbrainz.search_release_group(&arid, &album);
|
||||
let result = result.map(|list| MatchStateInfo::album(album, list));
|
||||
if Self::send_fetch_result(&fetch_tx, &events, result).is_err() {
|
||||
return;
|
||||
};
|
||||
|
||||
if album_iter.peek().is_some() {
|
||||
thread::sleep(time::Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn send_fetch_result(
|
||||
fetch_tx: &FetchSender,
|
||||
events: &EventSender,
|
||||
result: Result<MatchStateInfo, musicbrainz::api::Error>,
|
||||
) -> Result<(), ()> {
|
||||
// If receiver disconnects just drop the rest.
|
||||
fetch_tx.send(result).map_err(|_| ())?;
|
||||
|
||||
// If this send fails the event listener is dead. Don't panic as this function runs in a
|
||||
// detached thread so this might be happening during normal shut down.
|
||||
events.send(Event::FetchResultReady).map_err(|_| ())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AppMachine<FetchState>> for App {
|
||||
|
@ -8,16 +8,14 @@ mod match_state;
|
||||
mod reload_state;
|
||||
mod search_state;
|
||||
|
||||
use std::sync::{mpsc, Arc, Mutex};
|
||||
use std::sync::mpsc;
|
||||
|
||||
use crate::tui::{
|
||||
app::{
|
||||
selection::Selection, AppMode, AppPublic, AppPublicInner, AppPublicState, AppState, IApp,
|
||||
IAppAccess, IAppBase, IAppState,
|
||||
},
|
||||
event::EventSender,
|
||||
lib::{external::musicbrainz::daemon::Job, interface::musicbrainz::api::IMusicBrainz, IMusicHoard},
|
||||
RequestChannel,
|
||||
lib::{external::musicbrainz::daemon::Job, IMusicHoard},
|
||||
};
|
||||
|
||||
use browse_state::BrowseState;
|
||||
|
13
src/tui/lib/external/musicbrainz/daemon/mod.rs
vendored
13
src/tui/lib/external/musicbrainz/daemon/mod.rs
vendored
@ -163,14 +163,14 @@ impl MusicBrainzDaemon {
|
||||
api: MB,
|
||||
request_receiver: mpsc::Receiver<Job>,
|
||||
events: EventSender,
|
||||
) {
|
||||
) -> Result<(), Error> {
|
||||
let daemon = MusicBrainzDaemon {
|
||||
api: Box::new(api),
|
||||
request_receiver,
|
||||
job_queue: JobQueue::new(),
|
||||
events,
|
||||
};
|
||||
daemon.main();
|
||||
daemon.main()
|
||||
}
|
||||
|
||||
fn wait_for_jobs(&mut self) -> Result<(), Error> {
|
||||
@ -195,13 +195,12 @@ impl MusicBrainzDaemon {
|
||||
}
|
||||
|
||||
fn execute_next_job(&mut self) -> Option<()> {
|
||||
while let Some(instance) = self.job_queue.front_mut() {
|
||||
match instance.execute_next(&mut self.api, &mut self.events) {
|
||||
Some(()) => return Some(()),
|
||||
None => {
|
||||
if let Some(instance) = self.job_queue.front_mut() {
|
||||
let result = instance.execute_next(&mut self.api, &mut self.events);
|
||||
if result.is_none() {
|
||||
self.job_queue.pop_front();
|
||||
}
|
||||
}
|
||||
return Some(());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user