Synchronize feed updates

This commit is contained in:
Timofey 2020-01-08 22:32:43 +03:00 committed by Jordan Petridis
parent d38064e1c0
commit 1175a54266
3 changed files with 34 additions and 11 deletions

View File

@ -34,7 +34,7 @@ use gettextrs::{bindtextdomain, setlocale, textdomain, LocaleCategory};
use crossbeam_channel::Receiver; use crossbeam_channel::Receiver;
use fragile::Fragile; use fragile::Fragile;
use podcasts_data::Show; use podcasts_data::{Show, Source};
use crate::settings; use crate::settings;
use crate::stacks::PopulatedState; use crate::stacks::PopulatedState;
@ -138,7 +138,9 @@ pub(crate) enum Action {
HeaderBarShowTile(String), HeaderBarShowTile(String),
HeaderBarNormal, HeaderBarNormal,
MarkAllPlayerNotification(Arc<Show>), MarkAllPlayerNotification(Arc<Show>),
UpdateFeed(Option<Vec<Source>>),
ShowUpdateNotif(Receiver<bool>), ShowUpdateNotif(Receiver<bool>),
StopUpdating,
RemoveShow(Arc<Show>), RemoveShow(Arc<Show>),
ErrorNotification(String), ErrorNotification(String),
InitEpisode(i32), InitEpisode(i32),
@ -248,6 +250,17 @@ impl PdApplication {
let notif = InAppNotification::new(&err, 6000, callback, undo_cb); let notif = InAppNotification::new(&err, 6000, callback, undo_cb);
notif.show(&window.overlay); notif.show(&window.overlay);
} }
Action::UpdateFeed(source) => {
if window.updating.get() {
info!("Ignoring feed update request (another one is already running)")
} else {
window.updating.set(true);
utils::refresh_feed(source, window.sender.clone())
}
}
Action::StopUpdating => {
window.updating.set(false);
}
Action::ShowUpdateNotif(receiver) => { Action::ShowUpdateNotif(receiver) => {
let sender = window.sender.clone(); let sender = window.sender.clone();
let callback = move |revealer: gtk::Revealer| match receiver.try_recv() { let callback = move |revealer: gtk::Revealer| match receiver.try_recv() {
@ -255,9 +268,15 @@ impl PdApplication {
Err(TryRecvError::Disconnected) => glib::Continue(false), Err(TryRecvError::Disconnected) => glib::Continue(false),
Ok(_) => { Ok(_) => {
revealer.set_reveal_child(false); revealer.set_reveal_child(false);
sender
.send(Action::StopUpdating)
.expect("Action channel blew up somehow");
sender sender
.send(Action::RefreshAllViews) .send(Action::RefreshAllViews)
.expect("Action channel blew up somehow"); .expect("Action channel blew up somehow");
glib::Continue(false) glib::Continue(false)
} }
}; };
@ -269,6 +288,7 @@ impl PdApplication {
let old = window.updater.replace(Some(updater)); let old = window.updater.replace(Some(updater));
old.map(|i| i.destroy()); old.map(|i| i.destroy());
window window
.updater .updater
.borrow() .borrow()

View File

@ -203,10 +203,10 @@ pub(crate) fn cleanup(cleanup_date: DateTime<Utc>) {
.ok(); .ok();
} }
pub(crate) fn refresh<S>(source: Option<S>, sender: Sender<Action>) /// Schedule feed refresh
where /// If `source` is None, Refreshes all sources in the database.
S: IntoIterator<Item = Source> + Send + 'static, /// Current implementation ignores update request if another update is already running
{ pub(crate) fn refresh(source: Option<Vec<Source>>, sender: Sender<Action>) {
// If we try to update the whole db, // If we try to update the whole db,
// Exit early if `source` table is empty // Exit early if `source` table is empty
if source.is_none() { if source.is_none() {
@ -220,15 +220,16 @@ where
}; };
} }
refresh_feed(source, sender) sender
.send(Action::UpdateFeed(source))
.expect("Action channel blew up somehow")
} }
/// Update the rss feed(s) originating from `source`. /// Update the rss feed(s) originating from `source`.
/// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// If `source` is None, Fetches all the `Source` entries in the database and updates them.
fn refresh_feed<S>(source: Option<S>, sender: Sender<Action>) /// Do not call this function directly unless you are sure no other updates are running.
where /// Use `refresh()` instead
S: IntoIterator<Item = Source> + Send + 'static, pub(crate) fn refresh_feed(source: Option<Vec<Source>>, sender: Sender<Action>) {
{
rayon::spawn(move || { rayon::spawn(move || {
let (up_sender, up_receiver) = bounded(1); let (up_sender, up_receiver) = bounded(1);
sender sender

View File

@ -36,7 +36,7 @@ use crate::widgets::about_dialog;
use crate::widgets::appnotif::InAppNotification; use crate::widgets::appnotif::InAppNotification;
use crate::widgets::player; use crate::widgets::player;
use std::cell::RefCell; use std::cell::{Cell, RefCell};
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
@ -65,6 +65,7 @@ pub struct MainWindow {
pub(crate) content: Rc<Content>, pub(crate) content: Rc<Content>,
pub(crate) headerbar: Rc<Header>, pub(crate) headerbar: Rc<Header>,
pub(crate) player: player::PlayerWrapper, pub(crate) player: player::PlayerWrapper,
pub(crate) updating: Cell<bool>,
pub(crate) updater: RefCell<Option<InAppNotification>>, pub(crate) updater: RefCell<Option<InAppNotification>>,
pub(crate) sender: Sender<Action>, pub(crate) sender: Sender<Action>,
pub(crate) receiver: Receiver<Action>, pub(crate) receiver: Receiver<Action>,
@ -158,6 +159,7 @@ impl MainWindow {
headerbar: header, headerbar: header,
content, content,
player, player,
updating: Cell::new(false),
updater, updater,
sender, sender,
receiver, receiver,