Daemonize the musicbrainz thread #217

Merged
wojtek merged 15 commits from 188---add-option-for-manual-input-during-fetch into main 2024-09-21 23:03:47 +02:00
2 changed files with 29 additions and 18 deletions
Showing only changes of commit a67e6b937f - Show all commits

View File

@ -8,11 +8,10 @@ use musichoard::collection::{artist::Artist, musicbrainz::IMusicBrainzRef};
use crate::tui::{
app::{
machine::{match_state::MatchState, App, AppInner, AppMachine},
AppPublicState, AppState, IAppEventFetch, IAppInteractFetch, MatchStateInfo,
AppPublicState, AppState, IAppEventFetch, IAppInteractFetch,
},
lib::{
external::musicbrainz::daemon::{MbParams, ResultSender},
interface::musicbrainz::api::Error as MbError,
lib::external::musicbrainz::daemon::{
Error as DaemonError, IMbJobSender, MbApiResult, MbParams, ResultSender,
},
};
@ -20,16 +19,13 @@ pub struct FetchState {
fetch_rx: FetchReceiver,
}
pub type FetchReceiver = mpsc::Receiver<MbApiResult>;
impl FetchState {
pub fn new(fetch_rx: FetchReceiver) -> Self {
FetchState { fetch_rx }
}
}
pub type FetchError = MbError;
pub type FetchResult = Result<MatchStateInfo, FetchError>;
pub type FetchReceiver = mpsc::Receiver<FetchResult>;
impl AppMachine<FetchState> {
fn fetch_state(inner: AppInner, state: FetchState) -> Self {
AppMachine::new(inner, state)
@ -44,8 +40,10 @@ impl AppMachine<FetchState> {
}
};
let (fetch_tx, fetch_rx) = mpsc::channel::<FetchResult>();
Self::submit_fetch_job(&inner, artist, fetch_tx);
let (fetch_tx, fetch_rx) = mpsc::channel::<MbApiResult>();
if let Err(err) = Self::submit_fetch_job(&inner.musicbrainz, fetch_tx, artist) {
return AppMachine::error_state(inner, err.to_string()).into();
}
let fetch = FetchState::new(fetch_rx);
AppMachine::app_fetch(inner, fetch, true)
@ -79,19 +77,22 @@ impl AppMachine<FetchState> {
}
}
fn submit_fetch_job(inner: &AppInner, artist: &Artist, tx: ResultSender) {
let queue = match artist.meta.musicbrainz {
fn submit_fetch_job(
musicbrainz: &Box<dyn IMbJobSender>,
result_sender: ResultSender,
artist: &Artist,
) -> Result<(), DaemonError> {
let requests = match artist.meta.musicbrainz {
Some(ref arid) => {
let arid = arid.mbid();
artist
.albums
.iter()
let albums = artist.albums.iter();
albums
.map(|album| MbParams::search_release_group(arid.clone(), album.meta.clone()))
.collect()
}
None => VecDeque::from([MbParams::search_artist(artist.meta.clone())]),
};
inner.musicbrainz.submit_background_job(tx, queue);
musicbrainz.submit_background_job(result_sender, requests)
}
}

View File

@ -1,4 +1,4 @@
use std::{collections::VecDeque, sync::mpsc, thread, time};
use std::{collections::VecDeque, fmt, sync::mpsc, thread, time};
use musichoard::collection::{album::AlbumMeta, artist::ArtistMeta, musicbrainz::Mbid};
@ -13,6 +13,15 @@ pub enum Error {
JobChannelDisconnected,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::EventChannelDisconnected => write!(f, "the event channel is disconnected"),
Error::JobChannelDisconnected => write!(f, "the job channel is disconnected"),
}
}
}
pub struct MusicBrainzDaemon {
musicbrainz: Box<dyn IMusicBrainz>,
job_receiver: mpsc::Receiver<Job>,
@ -46,7 +55,8 @@ enum JobPriority {
Background,
}
pub type ResultSender = mpsc::Sender<Result<MatchStateInfo, ApiError>>;
pub type MbApiResult = Result<MatchStateInfo, ApiError>;
pub type ResultSender = mpsc::Sender<MbApiResult>;
struct JobInstance {
result_sender: ResultSender,
requests: VecDeque<MbParams>,