[geary/wip/unread-status-714865: 6/10] Only update one folder at a time
- From: Charles Lindsay <clindsay src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/unread-status-714865: 6/10] Only update one folder at a time
- Date: Fri, 21 Feb 2014 01:29:26 +0000 (UTC)
commit b3130c7eaffb45e084923270c76d59a897675c0a
Author: Charles Lindsay <chaz yorba org>
Date: Thu Feb 20 15:47:50 2014 -0800
Only update one folder at a time
.../imap-engine/imap-engine-generic-account.vala | 54 +++++++++----------
src/engine/imap/api/imap-account.vala | 43 ++++-----------
2 files changed, 38 insertions(+), 59 deletions(-)
---
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index 0b764c1..8ab2628 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -17,7 +17,8 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
private Gee.HashMap<FolderPath, MinimalFolder> folder_map = new Gee.HashMap<
FolderPath, MinimalFolder>();
private Gee.HashMap<FolderPath, Folder> local_only = new Gee.HashMap<FolderPath, Folder>();
- private uint refresh_unseen_timeout_id = 0;
+ private Gee.HashMap<FolderPath, uint> refresh_unseen_timeout_ids
+ = new Gee.HashMap<FolderPath, uint>();
private uint refresh_folder_timeout_id = 0;
private bool in_refresh_enumerate = false;
private Cancellable refresh_cancellable = new Cancellable();
@@ -72,23 +73,23 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
protected override void notify_email_appended(Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier>
ids) {
base.notify_email_appended(folder, ids);
- reschedule_unseen_update();
+ reschedule_unseen_update(folder);
}
protected override void notify_email_inserted(Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier>
ids) {
base.notify_email_inserted(folder, ids);
- reschedule_unseen_update();
+ reschedule_unseen_update(folder);
}
protected override void notify_email_removed(Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier>
ids) {
base.notify_email_removed(folder, ids);
- reschedule_unseen_update();
+ reschedule_unseen_update(folder);
}
protected override void notify_email_flags_changed(Geary.Folder folder,
Gee.Map<Geary.EmailIdentifier, Geary.EmailFlags> flag_map) {
base.notify_email_flags_changed(folder, flag_map);
- reschedule_unseen_update();
+ reschedule_unseen_update(folder);
}
private void check_open() throws EngineError {
@@ -284,22 +285,24 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
return all_folders;
}
- private void reschedule_unseen_update() {
- if (refresh_unseen_timeout_id != 0) {
- Source.remove(refresh_unseen_timeout_id);
- refresh_unseen_timeout_id = 0;
- }
+ private void reschedule_unseen_update(Geary.Folder folder) {
+ if (!folder_map.has_key(folder.path))
+ return;
- refresh_unseen_timeout_id = Timeout.add_seconds(REFRESH_UNSEEN_SEC, on_refresh_unseen);
+ if (refresh_unseen_timeout_ids.get(folder.path) != 0)
+ Source.remove(refresh_unseen_timeout_ids.get(folder.path));
+
+ refresh_unseen_timeout_ids.set(folder.path,
+ Timeout.add_seconds(REFRESH_UNSEEN_SEC, () => on_refresh_unseen(folder)));
}
- private bool on_refresh_unseen() {
+ private bool on_refresh_unseen(Geary.Folder folder) {
// TODO: prevent recursion?
// TODO: cancellable?
- refresh_unseen_async.begin(null, on_refresh_unseen_completed);
+ refresh_unseen_async.begin(folder, null, on_refresh_unseen_completed);
- refresh_unseen_timeout_id = 0;
+ refresh_unseen_timeout_ids.unset(folder.path);
return false;
}
@@ -311,20 +314,15 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
}
}
- private async void refresh_unseen_async(Cancellable? cancellable) throws Error {
- debug("Refreshing unseen counts");
+ private async void refresh_unseen_async(Geary.Folder folder, Cancellable? cancellable) throws Error {
+ debug("Refreshing unseen counts for %s", folder.to_string());
- Gee.Map<FolderPath, int> unseen_counts = yield remote.fetch_all_unseen_async(cancellable);
- foreach (FolderPath path in unseen_counts.keys) {
- if (!folder_map.has_key(path)) {
- debug("Unknown folder path %s returned from unseen counts", path.to_string());
- continue;
- }
-
- MinimalFolder folder = folder_map.get(path);
- folder.remote_folder.properties.set_status_unseen(unseen_counts.get(path));
- yield local.update_folder_status_async(folder.remote_folder, false, cancellable);
- }
+ int unseen_count = yield remote.fetch_unseen_count_async(folder.path, cancellable);
+
+ Imap.Folder remote_folder = yield remote.fetch_folder_async(folder.path, cancellable);
+ // TODO: nothing to refresh if that fetch just hit the network.
+ remote_folder.properties.set_status_unseen(unseen_count);
+ yield local.update_folder_status_async(remote_folder, false, cancellable);
}
private void reschedule_folder_refresh(bool immediate) {
diff --git a/src/engine/imap/api/imap-account.vala b/src/engine/imap/api/imap-account.vala
index 72f905d..976a9ba 100644
--- a/src/engine/imap/api/imap-account.vala
+++ b/src/engine/imap/api/imap-account.vala
@@ -183,7 +183,7 @@ private class Geary.Imap.Account : BaseObject {
Imap.Folder folder;
if (!mailbox_info.attrs.is_no_select) {
- StatusData status = yield fetch_status_async(path, cancellable);
+ StatusData status = yield fetch_status_async(path, StatusDataType.all(), cancellable);
folder = new Imap.Folder(session_mgr, status, mailbox_info);
} else {
@@ -195,13 +195,22 @@ private class Geary.Imap.Account : BaseObject {
return folder;
}
- private async StatusData fetch_status_async(FolderPath path, Cancellable? cancellable)
+ public async int fetch_unseen_count_async(FolderPath path, Cancellable? cancellable)
throws Error {
check_open();
+ // TODO: check mailbox_info.attrs.is_no_select first?
+ StatusData data = yield fetch_status_async(path, { StatusDataType.UNSEEN }, cancellable);
+ return data.unseen;
+ }
+
+ private async StatusData fetch_status_async(FolderPath path, StatusDataType[] status_types,
+ Cancellable? cancellable) throws Error {
+ check_open();
+
Gee.List<StatusData> status_results = new Gee.ArrayList<StatusData>();
StatusResponse response = yield send_command_async(
- new StatusCommand(new MailboxSpecifier.from_folder_path(path, null), StatusDataType.all()),
+ new StatusCommand(new MailboxSpecifier.from_folder_path(path, null), status_types),
null, status_results, cancellable);
throw_fetch_error(response, path, status_results.size);
@@ -224,34 +233,6 @@ private class Geary.Imap.Account : BaseObject {
}
}
- public async Gee.Map<FolderPath, int> fetch_all_unseen_async(Cancellable? cancellable) throws Error {
- Gee.HashMap<MailboxSpecifier, FolderPath> paths = new Gee.HashMap<MailboxSpecifier, FolderPath>();
- foreach (FolderPath p in folders.keys) {
- try {
- paths.set(new MailboxSpecifier.from_folder_path(p, null), p);
- } catch (Error e) {
- debug("Error converting folder path %s to mailbox specifier: %s", p.to_string(), e.message);
- }
- }
-
- Gee.ArrayList<StatusCommand> commands = Geary.traverse<MailboxSpecifier>(paths.keys)
- .map<StatusCommand>(m => new StatusCommand(m, { StatusDataType.UNSEEN }))
- .to_array_list();
- Gee.ArrayList<StatusData> status_results = new Gee.ArrayList<StatusData>();
- Gee.Map<Command, StatusResponse> responses = yield send_multiple_async(commands,
- null, status_results, cancellable);
-
- // TODO: check responses?
- (void) responses;
-
- Gee.HashMap<FolderPath, int> unseen_counts = new Gee.HashMap<FolderPath, int>();
- foreach (StatusData data in status_results) {
- assert(paths.has_key(data.mailbox));
- unseen_counts.set(paths.get(data.mailbox), data.unseen);
- }
- return unseen_counts;
- }
-
public async Gee.List<Imap.Folder>? list_child_folders_async(FolderPath? parent, Cancellable?
cancellable)
throws Error {
check_open();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]