Send MailboxUpdate events when threads are updated
Depending on the insertion order of folders which is non-deterministic because it relies on the kernel's scheduling of parsing threads, the listing the user sees might not be up-to-date because later thread updates are never broadcast. This results in inconsistencies between threads and mail listings when a thread's root envelope was part of a not broadcast update leading to `key not found` panics in a listing's hashmaps.embed
parent
3aec1f6dec
commit
bc7da4610e
|
@ -120,13 +120,15 @@ impl Collection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Merge new Mailbox to collection and update threads.
|
||||||
|
/// Returns a list of already existing folders whose threads were updated
|
||||||
pub fn merge(
|
pub fn merge(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut envelopes: FnvHashMap<EnvelopeHash, Envelope>,
|
mut envelopes: FnvHashMap<EnvelopeHash, Envelope>,
|
||||||
folder_hash: FolderHash,
|
folder_hash: FolderHash,
|
||||||
mailbox: &mut Mailbox,
|
mailbox: &mut Mailbox,
|
||||||
sent_folder: Option<FolderHash>,
|
sent_folder: Option<FolderHash>,
|
||||||
) {
|
) -> Option<StackVec<FolderHash>> {
|
||||||
self.sent_folder = sent_folder;
|
self.sent_folder = sent_folder;
|
||||||
envelopes.retain(|&h, e| {
|
envelopes.retain(|&h, e| {
|
||||||
if self.message_ids.contains_key(e.message_id().raw()) {
|
if self.message_ids.contains_key(e.message_id().raw()) {
|
||||||
|
@ -150,6 +152,8 @@ impl Collection {
|
||||||
ref sent_folder,
|
ref sent_folder,
|
||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
let mut ret = StackVec::new();
|
||||||
for (t_fh, t) in threads.iter_mut() {
|
for (t_fh, t) in threads.iter_mut() {
|
||||||
if sent_folder.map(|f| f == folder_hash).unwrap_or(false) {
|
if sent_folder.map(|f| f == folder_hash).unwrap_or(false) {
|
||||||
let mut ordered_hash_set = new_threads
|
let mut ordered_hash_set = new_threads
|
||||||
|
@ -163,8 +167,12 @@ impl Collection {
|
||||||
.partial_cmp(&envelopes[b].date())
|
.partial_cmp(&envelopes[b].date())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
let mut updated = false;
|
||||||
for h in ordered_hash_set {
|
for h in ordered_hash_set {
|
||||||
t.insert_reply(envelopes, h);
|
updated |= t.insert_reply(envelopes, h);
|
||||||
|
}
|
||||||
|
if updated {
|
||||||
|
ret.push(*t_fh);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -183,6 +191,11 @@ impl Collection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
threads.insert(folder_hash, new_threads);
|
threads.insert(folder_hash, new_threads);
|
||||||
|
if ret.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(ret)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, old_hash: EnvelopeHash, envelope: Envelope, folder_hash: FolderHash) {
|
pub fn update(&mut self, old_hash: EnvelopeHash, envelope: Envelope, folder_hash: FolderHash) {
|
||||||
|
|
|
@ -468,8 +468,14 @@ impl Account {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (envelopes, mut mailbox) = payload.unwrap();
|
let (envelopes, mut mailbox) = payload.unwrap();
|
||||||
self.collection
|
if let Some(updated_folders) =
|
||||||
.merge(envelopes, folder_hash, &mut mailbox, self.sent_folder);
|
self.collection
|
||||||
|
.merge(envelopes, folder_hash, &mut mailbox, self.sent_folder)
|
||||||
|
{
|
||||||
|
for f in updated_folders {
|
||||||
|
self.notify_fn.notify(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
self.folders
|
self.folders
|
||||||
.insert(folder_hash, MailboxEntry::Available(mailbox));
|
.insert(folder_hash, MailboxEntry::Available(mailbox));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue