isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit 1ea2e69aa7be3f7b8169ded9068d6c8854391158
parent 6705604c4a01a86546bf6ceed459cb49d37ea377
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Sun, 19 Mar 2017 11:35:57 +0100

fix maxuid tracking

newmaxuid represents the highest UID for which a sync entry was created,
while maxuid represents the end of the range which is guaranteed to have
been propagated. that means that the former needs to be instantly
incremented (and logged), while the latter must not be touched until the
entire new message sync completes. this matters particularly in the case
of resuming an interrupted run, where sync entry creation must resume
exactly where it left off, while loading the box must use the old limit
to ensure that all messages are available for actual propagation.

Diffstat:
Msrc/sync.c | 38+++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/src/sync.c b/src/sync.c @@ -826,9 +826,9 @@ load_state( sync_vars_t *svars ) buf[t] = 0; if ((c = buf[0]) == '#' ? (t3 = 0, (sscanf( buf + 2, "%d %d %n", &t1, &t2, &t3 ) < 2) || !t3 || (t - t3 != TUIDL + 2)) : - c == '!' ? + c == 'S' || c == '!' ? (sscanf( buf + 2, "%d", &t1 ) != 1) : - c == 'S' || c == 'F' || c == 'T' || c == '+' || c == '&' || c == '-' || c == '|' || c == '/' || c == '\\' ? + c == 'F' || c == 'T' || c == '+' || c == '&' || c == '-' || c == '|' || c == '/' || c == '\\' ? (sscanf( buf + 2, "%d %d", &t1, &t2 ) != 2) : (sscanf( buf + 2, "%d %d %d", &t1, &t2, &t3 ) != 3)) { @@ -836,7 +836,7 @@ load_state( sync_vars_t *svars ) goto jbail; } if (c == 'S') - svars->maxuid[t1] = t2; + svars->maxuid[t1] = svars->newmaxuid[t1]; else if (c == 'F') svars->newuid[t1] = t2; else if (c == 'T') @@ -1569,15 +1569,18 @@ box_loaded( int sts, void *aux ) debug( "synchronizing new entries\n" ); for (t = 0; t < 2; t++) { for (tmsg = svars->ctx[1-t]->msgs; tmsg; tmsg = tmsg->next) { - /* If we have a srec: - * - message is old (> 0) or expired (0) => ignore - * - message was skipped (-1) => ReNew - * - message was attempted, but failed (-2) => New - * If new have no srec, the message is always New. If messages were previously ignored - * due to being excessive, they would now appear to be newer than the messages that - * got actually synced, so make sure to look only at the newest ones. As some messages - * may be already propagated before an interruption, and maxuid logging is delayed, - * we need to track the newmaxuid separately. */ + // If new have no srec, the message is always New. If we have a srec: + // - message is old (> 0) or expired (0) => ignore + // - message was skipped (-1) => ReNew + // - message was attempted, but failed (-2) => New + // + // If messages were previously ignored due to being excessive, they would now + // appear to be newer than the messages that got actually synced, so increment + // newmaxuid immediately to make sure we always look only at the newest ones. + // However, committing it to maxuid must be delayed until all messages were + // propagated, to ensure that all pending messages are still loaded next time + // in case of interruption - in particular skipping big messages would otherwise + // up the limit too early. srec = tmsg->srec; if (srec ? srec->uid[t] < 0 && (svars->chan->ops[t] & (srec->uid[t] == -1 ? OP_RENEW : OP_NEW)) : svars->newmaxuid[1-t] < tmsg->uid && (svars->chan->ops[t] & OP_NEW)) { @@ -1606,12 +1609,6 @@ box_loaded( int sts, void *aux ) jFprintf( svars, "+ %d %d\n", srec->uid[M], srec->uid[S] ); debug( " -> pair(%d,%d) created\n", srec->uid[M], srec->uid[S] ); } - if (svars->maxuid[1-t] < tmsg->uid) { - /* We do this here for simplicity. However, logging must be delayed until - * all messages were propagated, as skipped messages could otherwise be - * logged before the propagation of messages with lower UIDs completes. */ - svars->maxuid[1-t] = tmsg->uid; - } if ((tmsg->flags & F_FLAGGED) || tmsg->size <= svars->chan->stores[t]->max_size) { if (tmsg->flags) { srec->flags = tmsg->flags; @@ -1923,7 +1920,10 @@ msgs_copied( sync_vars_t *svars, int t ) if (svars->new_pending[t]) goto out; - jFprintf( svars, "S %d %d\n", 1-t, svars->maxuid[1-t] ); + if (svars->maxuid[1-t] != svars->newmaxuid[1-t]) { + svars->maxuid[1-t] = svars->newmaxuid[1-t]; + jFprintf( svars, "S %d\n", 1-t ); + } sync_close( svars, 1-t ); if (check_cancel( svars )) goto out;