commit 74c78c70b973f95d4e9150e4da8284c01aa22b69
Author: Oswald Buddenhagen <[email protected]>
Date:   Sun Jan 4 00:39:06 2015 +0100

    deal sensibly with permanent errors
    
    don't retry dead Stores for every Channel.
    
    this also introduces a state for transient errors (specifically, connect
    failures), but this is currently unused.

 src/driver.h      |    5 +++++
 src/drv_imap.c    |   39 +++++++++++++++++++++++----------------
 src/drv_maildir.c |    5 ++++-
 src/main.c        |   11 ++++++++++-
 4 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/src/driver.h b/src/driver.h
index 9416686..e79a096 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -27,6 +27,10 @@
 
 typedef struct driver driver_t;
 
+#define FAIL_TEMP   0  /* Retry immediately (also: no error) */
+#define FAIL_WAIT   1  /* Retry after some time (if at all) */
+#define FAIL_FINAL  2  /* Don't retry until store reconfiguration */
+
 typedef struct store_conf {
        struct store_conf *next;
        char *name;
@@ -37,6 +41,7 @@ typedef struct store_conf {
        const char *trash;
        uint max_size; /* off_t is overkill */
        char trash_remote_new, trash_only_new;
+       char failed;
 } store_conf_t;
 
 /* For message->flags */
diff --git a/src/drv_imap.c b/src/drv_imap.c
index b9505dd..447bc6e 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -1508,7 +1508,13 @@ static void imap_open_store_finalize( imap_store_t * );
 #ifdef HAVE_LIBSSL
 static void imap_open_store_ssl_bail( imap_store_t * );
 #endif
-static void imap_open_store_bail( imap_store_t * );
+static void imap_open_store_bail( imap_store_t *, int );
+
+static void
+imap_open_store_bad( void *aux )
+{
+       imap_open_store_bail( (imap_store_t *)aux, FAIL_TEMP );
+}
 
 static void
 imap_open_store( store_conf_t *conf, const char *label,
@@ -1540,7 +1546,7 @@ imap_open_store( store_conf_t *conf, const char *label,
                        ctx->delimiter = 0;
                        ctx->callbacks.imap_open = cb;
                        ctx->callback_aux = aux;
-                       set_bad_callback( &ctx->gen, (void (*)(void 
*))imap_open_store_bail, ctx );
+                       set_bad_callback( &ctx->gen, imap_open_store_bad, ctx );
                        imap_open_store_namespace( ctx );
                        return;
                }
@@ -1551,7 +1557,7 @@ imap_open_store( store_conf_t *conf, const char *label,
        ctx->ref_count = 1;
        ctx->callbacks.imap_open = cb;
        ctx->callback_aux = aux;
-       set_bad_callback( &ctx->gen, (void (*)(void *))imap_open_store_bail, 
ctx );
+       set_bad_callback( &ctx->gen, imap_open_store_bad, ctx );
        ctx->in_progress_append = &ctx->in_progress;
        ctx->pending_append = &ctx->pending;
 
@@ -1571,7 +1577,7 @@ imap_open_store_connected( int ok, void *aux )
 #endif
 
        if (!ok)
-               imap_open_store_bail( ctx );
+               imap_open_store_bail( ctx, FAIL_WAIT );
 #ifdef HAVE_LIBSSL
        else if (srvc->ssl_type == SSL_IMAPS)
                socket_start_tls( &ctx->conn, imap_open_store_tlsstarted1 );
@@ -1602,7 +1608,7 @@ static void
 imap_open_store_p2( imap_store_t *ctx, struct imap_cmd *cmd ATTR_UNUSED, int 
response )
 {
        if (response == RESP_NO)
-               imap_open_store_bail( ctx );
+               imap_open_store_bail( ctx, FAIL_FINAL );
        else if (response == RESP_OK)
                imap_open_store_authenticate( ctx );
 }
@@ -1623,7 +1629,7 @@ imap_open_store_authenticate( imap_store_t *ctx )
                                return;
                        } else {
                                error( "IMAP error: SSL support not 
available\n" );
-                               imap_open_store_bail( ctx );
+                               imap_open_store_bail( ctx, FAIL_FINAL );
                                return;
                        }
                }
@@ -1633,7 +1639,7 @@ imap_open_store_authenticate( imap_store_t *ctx )
 #ifdef HAVE_LIBSSL
                if (srvc->ssl_type == SSL_STARTTLS) {
                        error( "IMAP error: SSL support not available\n" );
-                       imap_open_store_bail( ctx );
+                       imap_open_store_bail( ctx, FAIL_FINAL );
                        return;
                }
 #endif
@@ -1646,7 +1652,7 @@ static void
 imap_open_store_authenticate_p2( imap_store_t *ctx, struct imap_cmd *cmd 
ATTR_UNUSED, int response )
 {
        if (response == RESP_NO)
-               imap_open_store_bail( ctx );
+               imap_open_store_bail( ctx, FAIL_FINAL );
        else if (response == RESP_OK)
                socket_start_tls( &ctx->conn, imap_open_store_tlsstarted2 );
 }
@@ -1666,7 +1672,7 @@ static void
 imap_open_store_authenticate_p3( imap_store_t *ctx, struct imap_cmd *cmd 
ATTR_UNUSED, int response )
 {
        if (response == RESP_NO)
-               imap_open_store_bail( ctx );
+               imap_open_store_bail( ctx, FAIL_FINAL );
        else if (response == RESP_OK)
                imap_open_store_authenticate2( ctx );
 }
@@ -1872,7 +1878,7 @@ do_sasl_auth( imap_store_t *ctx, struct imap_cmd *cmdp 
ATTR_UNUSED, const char *
        return socket_write( &ctx->conn, iov, iovcnt );
 
   bail:
-       imap_open_store_bail( ctx );
+       imap_open_store_bail( ctx, FAIL_FINAL );
        return -1;
 }
 
@@ -1996,14 +2002,14 @@ imap_open_store_authenticate2( imap_store_t *ctx )
        error( "IMAP error: server supports no acceptable authentication 
mechanism\n" );
 
   bail:
-       imap_open_store_bail( ctx );
+       imap_open_store_bail( ctx, FAIL_FINAL );
 }
 
 static void
 imap_open_store_authenticate2_p2( imap_store_t *ctx, struct imap_cmd *cmd 
ATTR_UNUSED, int response )
 {
        if (response == RESP_NO)
-               imap_open_store_bail( ctx );
+               imap_open_store_bail( ctx, FAIL_FINAL );
        else if (response == RESP_OK)
                imap_open_store_namespace( ctx );
 }
@@ -2030,7 +2036,7 @@ static void
 imap_open_store_namespace_p2( imap_store_t *ctx, struct imap_cmd *cmd 
ATTR_UNUSED, int response )
 {
        if (response == RESP_NO) {
-               imap_open_store_bail( ctx );
+               imap_open_store_bail( ctx, FAIL_FINAL );
        } else if (response == RESP_OK) {
                ctx->got_namespace = 1;
                imap_open_store_namespace2( ctx );
@@ -2061,7 +2067,7 @@ imap_open_store_namespace2( imap_store_t *ctx )
 #endif
                imap_open_store_finalize( ctx );
        } else {
-               imap_open_store_bail( ctx );
+               imap_open_store_bail( ctx, FAIL_FINAL );
        }
 }
 
@@ -2095,15 +2101,16 @@ imap_open_store_ssl_bail( imap_store_t *ctx )
 {
        /* This avoids that we try to send LOGOUT to an unusable socket. */
        socket_close( &ctx->conn );
-       imap_open_store_bail( ctx );
+       imap_open_store_bail( ctx, FAIL_FINAL );
 }
 #endif
 
 static void
-imap_open_store_bail( imap_store_t *ctx )
+imap_open_store_bail( imap_store_t *ctx, int failed )
 {
        void (*cb)( store_t *srv, void *aux ) = ctx->callbacks.imap_open;
        void *aux = ctx->callback_aux;
+       ctx->gen.conf->failed = failed;
        imap_cancel_store( &ctx->gen );
        cb( 0, aux );
 }
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index 85313df..f6fa0c5 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -126,16 +126,18 @@ maildir_join_path( const char *prefix, const char *box )
 }
 
 static int
-maildir_validate_path( const store_conf_t *conf )
+maildir_validate_path( store_conf_t *conf )
 {
        struct stat st;
 
        if (!conf->path) {
                error( "Maildir error: store '%s' has no Path\n", conf->name );
+               conf->failed = FAIL_FINAL;
                return -1;
        }
        if (stat( conf->path, &st ) || !S_ISDIR(st.st_mode)) {
                error( "Maildir error: cannot open store '%s'\n", conf->path );
+               conf->failed = FAIL_FINAL;
                return -1;
        }
        return 0;
@@ -414,6 +416,7 @@ maildir_validate( const char *box, int create, 
maildir_store_t *ctx )
                        return DRV_BOX_BAD;
                if (make_box_dir( buf, bl )) {
                        sys_error( "Maildir error: cannot create mailbox '%s'", 
box );
+                       ctx->gen.conf->failed = FAIL_FINAL;
                        maildir_invoke_bad_callback( &ctx->gen );
                        return DRV_CANCELED;
                }
diff --git a/src/main.c b/src/main.c
index 6c0b822..beb6059 100644
--- a/src/main.c
+++ b/src/main.c
@@ -601,9 +601,17 @@ sync_chans( main_vars_t *mvars, int ent )
                merge_actions( mvars->chan, mvars->ops, XOP_HAVE_REMOVE, 
OP_REMOVE, 0 );
                merge_actions( mvars->chan, mvars->ops, XOP_HAVE_EXPUNGE, 
OP_EXPUNGE, 0 );
 
-               mvars->state[M] = mvars->state[S] = ST_FRESH;
                info( "Channel %s\n", mvars->chan->name );
                mvars->skip = mvars->cben = 0;
+               for (t = 0; t < 2; t++) {
+                       if (mvars->chan->stores[t]->failed != FAIL_TEMP) {
+                               info( "Skipping due to failed %s store %s.\n", 
str_ms[t], mvars->chan->stores[t]->name );
+                               mvars->skip = 1;
+                       }
+               }
+               if (mvars->skip)
+                       goto next2;
+               mvars->state[M] = mvars->state[S] = ST_FRESH;
                if (mvars->chan->stores[M]->driver->flags & 
mvars->chan->stores[S]->driver->flags & DRV_VERBOSE)
                        labels[M] = "M: ", labels[S] = "S: ";
                else
@@ -694,6 +702,7 @@ sync_chans( main_vars_t *mvars, int ent )
                free_string_list( mvars->cboxes );
                free_string_list( mvars->boxes[M] );
                free_string_list( mvars->boxes[S] );
+         next2:
                if (mvars->all) {
                        if (!(mvars->chan = mvars->chan->next))
                                break;

------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to