mirror of
https://git.meli.delivery/meli/meli
synced 2024-11-19 03:25:38 +00:00
ui: refactor watch thread spawning procedure
- Remove unnecessary parameters from watch(), reload() - Add NewThread event that adds new threads in work_controller.static_threads hashmap - removed obsolete field State.threads - silence watch thread error notifications
This commit is contained in:
parent
7732b851e6
commit
59f7f03d64
@ -373,8 +373,8 @@ fn run_app() -> Result<()> {
|
||||
state.check_accounts();
|
||||
state.redraw();
|
||||
},
|
||||
ThreadEvent::ThreadJoin(id) => {
|
||||
state.join(id);
|
||||
ThreadEvent::NewThread(id, name) => {
|
||||
state.new_thread(id, name);
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -38,7 +38,7 @@ use melib::StackVec;
|
||||
use text_processing::GlobMatch;
|
||||
|
||||
use crate::types::UIEvent::{self, EnvelopeRemove, EnvelopeRename, EnvelopeUpdate, Notification};
|
||||
use crate::{workers::WorkController, StatusEvent, ThreadEvent};
|
||||
use crate::{StatusEvent, ThreadEvent};
|
||||
use crossbeam::Sender;
|
||||
use std::collections::VecDeque;
|
||||
use std::fs;
|
||||
@ -162,6 +162,7 @@ pub struct Account {
|
||||
pub(crate) runtime_settings: AccountConf,
|
||||
pub(crate) backend: Arc<RwLock<Box<dyn MailBackend>>>,
|
||||
|
||||
sender: Sender<ThreadEvent>,
|
||||
event_queue: VecDeque<(FolderHash, RefreshEvent)>,
|
||||
notify_fn: Arc<NotifyFn>,
|
||||
}
|
||||
@ -245,6 +246,7 @@ impl Account {
|
||||
mut settings: AccountConf,
|
||||
map: &Backends,
|
||||
work_context: WorkContext,
|
||||
sender: Sender<ThreadEvent>,
|
||||
notify_fn: NotifyFn,
|
||||
) -> Result<Self> {
|
||||
let s = settings.clone();
|
||||
@ -300,6 +302,7 @@ impl Account {
|
||||
settings,
|
||||
backend: Arc::new(RwLock::new(backend)),
|
||||
notify_fn,
|
||||
sender,
|
||||
|
||||
event_queue: VecDeque::with_capacity(8),
|
||||
})
|
||||
@ -514,16 +517,7 @@ impl Account {
|
||||
}
|
||||
Some(w)
|
||||
}
|
||||
pub fn reload(
|
||||
&mut self,
|
||||
event: RefreshEvent,
|
||||
folder_hash: FolderHash,
|
||||
context: (
|
||||
&mut WorkController,
|
||||
&Sender<ThreadEvent>,
|
||||
&mut VecDeque<UIEvent>,
|
||||
),
|
||||
) -> Option<UIEvent> {
|
||||
pub fn reload(&mut self, event: RefreshEvent, folder_hash: FolderHash) -> Option<UIEvent> {
|
||||
if !self.folders[&folder_hash].is_available() {
|
||||
self.event_queue.push_back((folder_hash, event));
|
||||
return None;
|
||||
@ -683,6 +677,7 @@ impl Account {
|
||||
}
|
||||
RefreshEventKind::Failure(e) => {
|
||||
debug!("RefreshEvent Failure: {}", e.to_string());
|
||||
/*
|
||||
context
|
||||
.1
|
||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||
@ -691,43 +686,39 @@ impl Account {
|
||||
Some(crate::types::NotificationType::ERROR),
|
||||
)))
|
||||
.expect("Could not send event on main channel");
|
||||
self.watch(context);
|
||||
*/
|
||||
self.watch();
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
pub fn watch(
|
||||
&self,
|
||||
context: (
|
||||
&mut WorkController,
|
||||
&Sender<ThreadEvent>,
|
||||
&mut VecDeque<UIEvent>,
|
||||
),
|
||||
) {
|
||||
let (work_controller, sender, replies) = context;
|
||||
let sender = sender.clone();
|
||||
pub fn watch(&self) {
|
||||
let sender_ = self.sender.clone();
|
||||
let r = RefreshEventConsumer::new(Box::new(move |r| {
|
||||
sender.send(ThreadEvent::from(r)).unwrap();
|
||||
sender_.send(ThreadEvent::from(r)).unwrap();
|
||||
}));
|
||||
match self
|
||||
.backend
|
||||
.read()
|
||||
.unwrap()
|
||||
.watch(r, work_controller.get_context())
|
||||
.watch(r, self.work_context.clone())
|
||||
{
|
||||
Ok(id) => {
|
||||
work_controller
|
||||
.static_threads
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(id, format!("watching {}", self.name()).into());
|
||||
self.sender
|
||||
.send(ThreadEvent::NewThread(
|
||||
id,
|
||||
format!("watching {}", self.name()).into(),
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
Err(e) => {
|
||||
replies.push_back(UIEvent::StatusEvent(StatusEvent::DisplayMessage(
|
||||
e.to_string(),
|
||||
)));
|
||||
self.sender
|
||||
.send(ThreadEvent::UIEvent(UIEvent::StatusEvent(
|
||||
StatusEvent::DisplayMessage(e.to_string()),
|
||||
)))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,9 +137,6 @@ impl Context {
|
||||
|
||||
pub fn is_online(&mut self, account_pos: usize) -> bool {
|
||||
let Context {
|
||||
ref mut work_controller,
|
||||
ref sender,
|
||||
ref mut replies,
|
||||
ref mut accounts,
|
||||
ref mut mailbox_hashes,
|
||||
..
|
||||
@ -158,7 +155,7 @@ impl Context {
|
||||
* inform the main binary that refresh events arrived
|
||||
* - replies to report any failures to the user
|
||||
*/
|
||||
accounts[account_pos].watch((work_controller, sender, replies));
|
||||
accounts[account_pos].watch();
|
||||
}
|
||||
true
|
||||
} else {
|
||||
@ -184,7 +181,6 @@ pub struct State {
|
||||
components: Vec<Box<dyn Component>>,
|
||||
pub context: Context,
|
||||
timer: thread::JoinHandle<()>,
|
||||
threads: FnvHashMap<thread::ThreadId, (Sender<bool>, thread::JoinHandle<()>)>,
|
||||
}
|
||||
|
||||
impl Drop for State {
|
||||
@ -232,6 +228,7 @@ impl State {
|
||||
a_s.clone(),
|
||||
&backends,
|
||||
work_controller.get_context(),
|
||||
sender.clone(),
|
||||
NotifyFn::new(Box::new(move |f: FolderHash| {
|
||||
sender
|
||||
.send(ThreadEvent::UIEvent(UIEvent::StartupCheck(f)))
|
||||
@ -286,7 +283,6 @@ impl State {
|
||||
tx: input_thread.0,
|
||||
},
|
||||
},
|
||||
threads: FnvHashMap::with_capacity_and_hasher(1, Default::default()),
|
||||
};
|
||||
if s.context.settings.terminal.ascii_drawing {
|
||||
s.grid.set_ascii_drawing(true);
|
||||
@ -319,41 +315,29 @@ impl State {
|
||||
return;
|
||||
}
|
||||
let Context {
|
||||
ref mut work_controller,
|
||||
ref sender,
|
||||
ref mut replies,
|
||||
ref mut accounts,
|
||||
..
|
||||
ref mut accounts, ..
|
||||
} = &mut self.context;
|
||||
|
||||
if let Some(notification) =
|
||||
accounts[idxa].reload(event, hash, (work_controller, sender, replies))
|
||||
{
|
||||
if let Some(notification) = accounts[idxa].reload(event, hash) {
|
||||
if let UIEvent::Notification(_, _, _) = notification {
|
||||
self.rcv_event(UIEvent::MailboxUpdate((idxa, hash)));
|
||||
}
|
||||
self.rcv_event(notification);
|
||||
}
|
||||
} else {
|
||||
if let melib::backends::RefreshEventKind::Failure(e) = event.kind() {
|
||||
self.context
|
||||
.sender
|
||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||
Some("watcher thread exited with error".to_string()),
|
||||
e.to_string(),
|
||||
Some(crate::types::NotificationType::ERROR),
|
||||
)))
|
||||
.expect("Could not send event on main channel");
|
||||
if let melib::backends::RefreshEventKind::Failure(err) = event.kind() {
|
||||
debug!(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If an owned thread returns a `ThreadEvent::ThreadJoin` event to `State` then it must remove
|
||||
/// the thread from its list and `join` it.
|
||||
pub fn join(&mut self, id: thread::ThreadId) {
|
||||
let (tx, handle) = self.threads.remove(&id).unwrap();
|
||||
tx.send(true).unwrap();
|
||||
handle.join().unwrap();
|
||||
pub fn new_thread(&mut self, id: thread::ThreadId, name: String) {
|
||||
self.context
|
||||
.work_controller
|
||||
.static_threads
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(id, name.into());
|
||||
}
|
||||
|
||||
/// Switch back to the terminal's main screen (The command line the user sees before opening
|
||||
|
@ -46,7 +46,7 @@ pub enum StatusEvent {
|
||||
/// to the main process.
|
||||
#[derive(Debug)]
|
||||
pub enum ThreadEvent {
|
||||
ThreadJoin(thread::ThreadId),
|
||||
NewThread(thread::ThreadId, String),
|
||||
/// User input.
|
||||
Input(Key),
|
||||
/// User input and input as raw bytes.
|
||||
|
Loading…
Reference in New Issue
Block a user