Mercurial > dovecot > core-2.2
changeset 15625:b21f3119a5ee
replicator: Use stateful dsyncing whenever possible.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 10 Jan 2013 07:54:39 +0200 |
parents | 59cef0c673b4 |
children | 1a47a0df6ad0 |
files | src/replication/replicator/doveadm-connection.c src/replication/replicator/doveadm-connection.h src/replication/replicator/replicator-brain.c src/replication/replicator/replicator-queue.c src/replication/replicator/replicator-queue.h |
diffstat | 5 files changed, 29 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/src/replication/replicator/doveadm-connection.c Thu Jan 10 07:53:26 2013 +0200 +++ b/src/replication/replicator/doveadm-connection.c Thu Jan 10 07:54:39 2013 +0200 @@ -13,7 +13,6 @@ #define DOVEADM_FAIL_TIMEOUT_MSECS (1000*5) #define DOVEADM_HANDSHAKE "VERSION\tdoveadm-server\t1\t0\n" -#define MAX_INBUF_SIZE 1024 struct doveadm_connection { char *path; @@ -23,12 +22,12 @@ struct ostream *output; struct timeout *to; + char *state; doveadm_callback_t *callback; void *context; time_t last_connect_failure; unsigned int handshaked:1; - unsigned int end_of_print:1; unsigned int cmd_sent:1; }; @@ -43,7 +42,7 @@ } static void doveadm_callback(struct doveadm_connection *conn, - enum doveadm_reply reply) + const char *state, enum doveadm_reply reply) { doveadm_callback_t *callback = conn->callback; void *context = conn->context; @@ -53,7 +52,7 @@ conn->callback = NULL; conn->context = NULL; - callback(reply, context); + callback(reply, state, context); } static void doveadm_close(struct doveadm_connection *conn) @@ -67,7 +66,7 @@ if (close(conn->fd) < 0) i_error("close(doveadm) failed: %m"); conn->fd = -1; - conn->end_of_print = FALSE; + i_free_and_null(conn->state); conn->cmd_sent = FALSE; conn->handshaked = FALSE; } @@ -76,7 +75,7 @@ { doveadm_close(conn); if (conn->callback != NULL) - doveadm_callback(conn, DOVEADM_REPLY_FAIL); + doveadm_callback(conn, "", DOVEADM_REPLY_FAIL); } void doveadm_connection_deinit(struct doveadm_connection **_conn) @@ -92,6 +91,8 @@ static int doveadm_input_line(struct doveadm_connection *conn, const char *line) { + const char *state; + if (!conn->handshaked) { if (strcmp(line, "+") != 0) { i_error("%s: Unexpected handshake: %s", @@ -105,21 +106,21 @@ i_error("%s: Unexpected input: %s", conn->path, line); return -1; } - if (!conn->end_of_print) { - if (line[0] == '\0') - conn->end_of_print = TRUE; + if (conn->state == NULL) { + conn->state = i_strdup(t_strcut(line, '\t')); return 0; } + state = t_strdup(conn->state); line = t_strdup(line); doveadm_close(conn); if (line[0] == '+') - doveadm_callback(conn, DOVEADM_REPLY_OK); + doveadm_callback(conn, state, DOVEADM_REPLY_OK); else if (line[0] == '-') { if (strcmp(line+1, "NOUSER") == 0) - doveadm_callback(conn, DOVEADM_REPLY_NOUSER); + doveadm_callback(conn, "", DOVEADM_REPLY_NOUSER); else - doveadm_callback(conn, DOVEADM_REPLY_FAIL); + doveadm_callback(conn, "", DOVEADM_REPLY_FAIL); } else { i_error("%s: Invalid input: %s", conn->path, line); return -1; @@ -160,7 +161,7 @@ } conn->last_connect_failure = 0; conn->io = io_add(conn->fd, IO_READ, doveadm_input, conn); - conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE, FALSE); + conn->input = i_stream_create_fd(conn->fd, (size_t)-1, FALSE); conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); o_stream_set_no_error_handling(conn->output, TRUE); o_stream_nsend_str(conn->output, DOVEADM_HANDSHAKE); @@ -173,7 +174,7 @@ } void doveadm_connection_sync(struct doveadm_connection *conn, - const char *username, bool full, + const char *username, const char *state, bool full, doveadm_callback_t *callback, void *context) { string_t *cmd; @@ -197,6 +198,9 @@ str_append(cmd, "\tsync\t-d"); if (full) str_append(cmd, "\t-f"); + str_append(cmd, "\t-s\t"); + if (state != NULL) + str_append(cmd, state); str_append_c(cmd, '\n'); o_stream_nsend(conn->output, str_data(cmd), str_len(cmd)); }
--- a/src/replication/replicator/doveadm-connection.h Thu Jan 10 07:53:26 2013 +0200 +++ b/src/replication/replicator/doveadm-connection.h Thu Jan 10 07:54:39 2013 +0200 @@ -7,13 +7,14 @@ DOVEADM_REPLY_NOUSER }; -typedef void doveadm_callback_t(enum doveadm_reply reply, void *context); +typedef void doveadm_callback_t(enum doveadm_reply reply, + const char *state, void *context); struct doveadm_connection *doveadm_connection_init(const char *path); void doveadm_connection_deinit(struct doveadm_connection **conn); void doveadm_connection_sync(struct doveadm_connection *conn, - const char *username, bool full, + const char *username, const char *state, bool full, doveadm_callback_t *callback, void *context); bool doveadm_connection_is_busy(struct doveadm_connection *conn);
--- a/src/replication/replicator/replicator-brain.c Thu Jan 10 07:53:26 2013 +0200 +++ b/src/replication/replicator/replicator-brain.c Thu Jan 10 07:54:39 2013 +0200 @@ -82,7 +82,8 @@ return conn; } -static void doveadm_sync_callback(enum doveadm_reply reply, void *context) +static void doveadm_sync_callback(enum doveadm_reply reply, const char *state, + void *context) { struct replicator_sync_context *ctx = context; @@ -90,6 +91,8 @@ /* user no longer exists, remove from replication */ replicator_queue_remove(ctx->brain->queue, &ctx->user); } else { + i_free(ctx->user->state); + ctx->user->state = i_strdup_empty(state); ctx->user->last_sync_failed = reply != DOVEADM_REPLY_OK; replicator_queue_push(ctx->brain->queue, ctx->user); @@ -125,7 +128,7 @@ ctx = i_new(struct replicator_sync_context, 1); ctx->brain = brain; ctx->user = user; - doveadm_connection_sync(conn, user->username, full, + doveadm_connection_sync(conn, user->username, user->state, full, doveadm_sync_callback, ctx); return TRUE; }
--- a/src/replication/replicator/replicator-queue.c Thu Jan 10 07:53:26 2013 +0200 +++ b/src/replication/replicator/replicator-queue.c Thu Jan 10 07:54:39 2013 +0200 @@ -174,6 +174,7 @@ priorityq_remove(queue->user_queue, &user->item); hash_table_remove(queue->user_hash, user->username); + i_free(user->state); i_free(user->username); i_free(user);
--- a/src/replication/replicator/replicator-queue.h Thu Jan 10 07:53:26 2013 +0200 +++ b/src/replication/replicator/replicator-queue.h Thu Jan 10 07:54:39 2013 +0200 @@ -8,12 +8,13 @@ struct priorityq_item item; char *username; - enum replication_priority priority; + char *state; /* last time this user's state was updated */ time_t last_update; /* last_fast_run is always >= last_full_run. */ time_t last_fast_sync, last_full_sync; + enum replication_priority priority; /* User isn't currently in replication queue */ unsigned int popped:1; /* Last replication sync failed */