[evolution-data-server] Revamp imapx_job_refresh_info_start() to make use of modseq and uidnext
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Revamp imapx_job_refresh_info_start() to make use of modseq and uidnext
- Date: Thu, 24 Jun 2010 13:03:03 +0000 (UTC)
commit b0214462be6e21c2a312d8fe3e31ffdd2825d153
Author: David Woodhouse <David Woodhouse intel com>
Date: Thu Jun 24 13:13:03 2010 +0100
Revamp imapx_job_refresh_info_start() to make use of modseq and uidnext
camel/providers/imapx/camel-imapx-server.c | 131 ++++++++++++++++++++--------
1 files changed, 94 insertions(+), 37 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 707dd6a..8dfda07 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -3597,64 +3597,121 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
{
guint32 total;
CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) job->folder;
+ CamelIMAPXSummary *isum = (CamelIMAPXSummary *)job->folder->summary;
CamelFolder *folder = job->folder;
CamelException *ex = job->ex;
const gchar *full_name;
+ gboolean need_rescan = FALSE;
+ gboolean is_selected = FALSE;
full_name = camel_folder_get_full_name (folder);
- total = camel_folder_summary_count (folder->summary);
- /* Check if there are any new messages. The old imap doc says one needs to reselect in case of inbox to fetch
- new messages. Need to check if its still true. Just use noop now */
- if (ifolder->exists_on_server == total) {
- camel_imapx_server_noop (is, folder, ex);
-
- if (camel_exception_is_set (ex))
- goto done;
- }
-
- /* Fetch the new messages */
- if (ifolder->exists_on_server > total)
- {
- imapx_server_fetch_new_messages (is, folder, FALSE, job->ex);
- if (camel_exception_is_set (job->ex))
- goto done;
- }
-
- /* Sync changes before fetching status, else unread count will not match. need to think about better ways for this */
+ /* Sync changes first, else unread count will not
+ match. Need to think about better ways for this */
imapx_server_sync_changes (is, folder, job->pri, ex);
if (camel_exception_is_set (job->ex))
goto done;
- /* Check if a rescan is needed */
+ if (is->select && !strcmp(full_name, is->select))
+ is_selected = TRUE;
+
total = camel_folder_summary_count (folder->summary);
- if (ifolder->exists_on_server == total) {
- guint32 unread;
+
+ /* We don't have valid unread count or modseq for currently-selected server
+ (unless we want to re-SELECT it). We fake unread count when fetching
+ message flags, but don't depend on modseq for the selected folder */
+ if (total != ifolder->exists_on_server ||
+ isum->uidnext != ifolder->uidnext_on_server ||
+ folder->summary->unread_count != ifolder->unread_on_server ||
+ (!is_selected && isum->modseq != ifolder->modseq_on_server))
+ need_rescan = TRUE;
+
+ /* This is probably the first check of this folder after startup;
+ use STATUS to check whether the cached summary is valid, rather
+ than blindly updating. Only for servers which support CONDSTORE
+ though. */
+ if ((isum->modseq && !ifolder->modseq_on_server))
+ need_rescan = FALSE;
+
+ /* If we don't think there's anything to do, poke it to check */
+ if (!need_rescan) {
CamelIMAPXCommand *ic;
+
+ if (is_selected) {
+ /* We may not issue STATUS on the current folder. Use SELECT or NOOP instead. */
+ if (0 /* server needs SELECT not just NOOP*/) {
+ if (imapx_idle_supported(is) && imapx_in_idle(is))
+ imapx_stop_idle(is, job->ex);
+ if (camel_exception_is_set(job->ex))
+ goto done;
+ /* This doesn't work -- this is an immediate command, not queued */
+ imapx_select(is, folder, TRUE, job->ex);
+ if (camel_exception_is_set(job->ex))
+ goto done;
+ } else {
+ /* Or maybe just NOOP, unless we're in IDLE in which case do nothing */
+ if (!imapx_idle_supported(is) || !imapx_in_idle(is)) {
+ camel_imapx_server_noop(is, folder, job->ex);
+ if (camel_exception_is_set(job->ex))
+ goto done;
+ }
+ }
+ } else {
+ if (is->cinfo->capa & IMAPX_CAPABILITY_CONDSTORE)
+ ic = camel_imapx_command_new (is, "STATUS", NULL, "STATUS %f (MESSAGES UNSEEN UIDNEXT HIGHESTMODSEQ)", folder);
+ else
+ ic = camel_imapx_command_new (is, "STATUS", NULL, "STATUS %f (MESSAGES UNSEEN UIDNEXT)", folder);
+
+ ic->job = job;
+ ic->pri = job->pri;
- ic = camel_imapx_command_new (is, "STATUS", full_name, "STATUS %f (MESSAGES UNSEEN)", folder);
- ic->job = job;
- ic->pri = job->pri;
- imapx_command_run_sync (is, ic);
+ imapx_command_run_sync (is, ic);
- if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
- if (!camel_exception_is_set (ic->ex))
- camel_exception_setv(job->ex, 1, "Error refreshing folder: %s", ic->status->text);
- else
- camel_exception_xfer (job->ex, ic->ex);
+ if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
+ if (!camel_exception_is_set (ic->ex))
+ camel_exception_setv(job->ex, 1, "Error refreshing folder: %s", ic->status->text);
+ else
+ camel_exception_xfer (job->ex, ic->ex);
+ camel_imapx_command_free (ic);
+ goto done;
+ }
camel_imapx_command_free (ic);
- goto done;
}
- camel_imapx_command_free (ic);
- unread = folder->summary->unread_count;
- if (ifolder->exists_on_server == total && unread == ifolder->unread_on_server)
+ /* Recalulate need_rescan */
+ if (total != ifolder->exists_on_server ||
+ isum->uidnext != ifolder->uidnext_on_server ||
+ folder->summary->unread_count != ifolder->unread_on_server ||
+ (!is_selected && isum->modseq != ifolder->modseq_on_server))
+ need_rescan = TRUE;
+
+ }
+
+ e(printf("folder %s is %sselected, total %u / %u, unread %u / %u, modseq %llu / %llu, uidnext %u / %u: will %srescan\n",
+ full_name, is_selected?"": "not ", total, ifolder->exists_on_server,
+ folder->summary->unread_count, ifolder->unread_on_server,
+ (unsigned long long)isum->modseq, (unsigned long long)ifolder->modseq_on_server,
+ isum->uidnext, ifolder->uidnext_on_server,
+ need_rescan?"":"not "));
+
+ /* Fetch new messages first, so that they appear to the user ASAP */
+ if (ifolder->exists_on_server > total ||
+ ifolder->uidnext_on_server > isum->uidnext)
+ {
+ if (!total)
+ need_rescan = FALSE;
+
+ imapx_server_fetch_new_messages (is, folder, FALSE, job->ex);
+ if (camel_exception_is_set (job->ex))
goto done;
}
- imapx_job_scan_changes_start (is, job);
- return;
+ /* Refetch flags for the entire folder */
+ if (need_rescan) {
+ imapx_job_scan_changes_start (is, job);
+ return;
+ }
done:
imapx_job_done (is, job);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]