dovecot-2.1: fts: Added fts_index_timeout setting to abort searc...

dovecot at dovecot.org dovecot at dovecot.org
Mon Mar 12 13:45:25 EET 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/4dd97a92691a
changeset: 14291:4dd97a92691a
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Mar 12 13:45:19 2012 +0200
description:
fts: Added fts_index_timeout setting to abort search if indexing hasn't finished by then.
This timeout shows up to client as:
tag NO [INUSE] Timeout while waiting for indexing to finish

diffstat:

 src/plugins/fts/Makefile.am   |   1 +
 src/plugins/fts/fts-indexer.c |  25 +++++++++++++++++++++++--
 src/plugins/fts/fts-storage.c |  26 +++++++++++++++++++++++++-
 src/plugins/fts/fts-storage.h |   1 +
 4 files changed, 50 insertions(+), 3 deletions(-)

diffs (172 lines):

diff -r d27b6724db32 -r 4dd97a92691a src/plugins/fts/Makefile.am
--- a/src/plugins/fts/Makefile.am	Mon Mar 12 13:17:50 2012 +0200
+++ b/src/plugins/fts/Makefile.am	Mon Mar 12 13:45:19 2012 +0200
@@ -3,6 +3,7 @@
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/lib \
+	-I$(top_srcdir)/src/lib-settings \
 	-I$(top_srcdir)/src/lib-mail \
 	-I$(top_srcdir)/src/lib-index \
 	-I$(top_srcdir)/src/lib-storage \
diff -r d27b6724db32 -r 4dd97a92691a src/plugins/fts/fts-indexer.c
--- a/src/plugins/fts/fts-indexer.c	Mon Mar 12 13:17:50 2012 +0200
+++ b/src/plugins/fts/fts-indexer.c	Mon Mar 12 13:45:19 2012 +0200
@@ -7,6 +7,7 @@
 #include "write-full.h"
 #include "strescape.h"
 #include "time-util.h"
+#include "settings-parser.h"
 #include "mail-user.h"
 #include "mail-storage-private.h"
 #include "fts-api.h"
@@ -23,6 +24,7 @@
 
 	struct timeval search_start_time, last_notify;
 	unsigned int percentage;
+	unsigned int timeout_secs;
 
 	char *path;
 	int fd;
@@ -93,7 +95,7 @@
 	struct fts_indexer_context *ctx;
 	struct mailbox_status status;
 	uint32_t last_uid, seq1, seq2;
-	const char *path, *cmd;
+	const char *path, *cmd, *value, *error;
 	int fd;
 
 	if (fts_backend_get_last_uid(backend, box, &last_uid) < 0)
@@ -126,6 +128,13 @@
 	ctx->input = i_stream_create_fd(fd, 128, FALSE);
 	ctx->search_start_time = ioloop_timeval;
 
+	value = mail_user_plugin_getenv(box->storage->user, "fts_index_timeout");
+	if (value != NULL) {
+		if (settings_get_time(value, &ctx->timeout_secs, &error) < 0)
+			i_error("Invalid fts_index_timeout setting: %s", error);
+	}
+
+
 	*ctx_r = ctx;
 	return 1;
 }
@@ -214,12 +223,24 @@
 
 int fts_indexer_more(struct fts_indexer_context *ctx)
 {
-	int ret;
+	int ret, diff;
 
 	if ((ret = fts_indexer_more_int(ctx)) < 0) {
+		mail_storage_set_internal_error(ctx->box->storage);
 		ctx->failed = TRUE;
 		return -1;
 	}
+
+	if (ctx->timeout_secs > 0) {
+		diff = ioloop_time - ctx->search_start_time.tv_sec;
+		if (diff > (int)ctx->timeout_secs) {
+			mail_storage_set_error(ctx->box->storage,
+				MAIL_ERROR_INUSE,
+				"Timeout while waiting for indexing to finish");
+			ctx->failed = TRUE;
+			return -1;
+		}
+	}
 	if (ret == 0)
 		fts_indexer_notify(ctx);
 	return ret;
diff -r d27b6724db32 -r 4dd97a92691a src/plugins/fts/fts-storage.c
--- a/src/plugins/fts/fts-storage.c	Mon Mar 12 13:17:50 2012 +0200
+++ b/src/plugins/fts/fts-storage.c	Mon Mar 12 13:45:19 2012 +0200
@@ -203,6 +203,7 @@
 static bool fts_mailbox_build_continue(struct mail_search_context *ctx)
 {
 	struct fts_search_context *fctx = FTS_CONTEXT(ctx);
+	enum mail_error error;
 	int ret;
 
 	if (fctx == NULL)
@@ -218,6 +219,17 @@
 			ret = -1;
 		if (ret > 0)
 			fts_search_lookup(fctx);
+		if (ret < 0) {
+			/* if indexing timed out, it probably means that
+			   the mailbox is still being indexed, but it's a large
+			   mailbox and it takes a while. in this situation
+			   we'll simply abort the search.
+
+			   if indexing failed for any other reason, just
+			   fallback to searching the slow way. */
+			(void)mailbox_get_last_error(fctx->box, &error);
+			fctx->indexing_timed_out = error == MAIL_ERROR_INUSE;
+		}
 	}
 	return TRUE;
 }
@@ -227,11 +239,16 @@
 				 struct mail **mail_r, bool *tryagain_r)
 {
 	struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
+	struct fts_search_context *fctx = FTS_CONTEXT(ctx);
 
 	if (!fts_mailbox_build_continue(ctx)) {
 		*tryagain_r = TRUE;
 		return FALSE;
 	}
+	if (fctx->indexing_timed_out) {
+		*tryagain_r = FALSE;
+		return FALSE;
+	}
 
 	return fbox->module_ctx.super.
 		search_next_nonblock(ctx, mail_r, tryagain_r);
@@ -270,6 +287,8 @@
 
 	if (fctx == NULL || !fctx->fts_lookup_success) {
 		/* fts lookup not done for this search */
+		if (fctx->indexing_timed_out)
+			return FALSE;
 		return fbox->module_ctx.super.search_next_update_seq(ctx);
 	}
 
@@ -295,12 +314,15 @@
 	struct fts_mailbox *fbox = FTS_CONTEXT(ctx->transaction->box);
 	struct fts_transaction_context *ft = FTS_CONTEXT(ctx->transaction);
 	struct fts_search_context *fctx = FTS_CONTEXT(ctx);
+	int ret = 0;
 
 	if (fctx != NULL) {
 		if (fctx->indexer_ctx != NULL) {
 			if (fts_indexer_deinit(&fctx->indexer_ctx) < 0)
 				ft->failed = TRUE;
 		}
+		if (fctx->indexing_timed_out)
+			ret = -1;
 
 		buffer_free(&fctx->orig_matches);
 		array_free(&fctx->levels);
@@ -308,7 +330,9 @@
 		fts_scores_unref(&fctx->scores);
 		i_free(fctx);
 	}
-	return fbox->module_ctx.super.search_deinit(ctx);
+	if (fbox->module_ctx.super.search_deinit(ctx) < 0)
+		ret = -1;
+	return ret;
 }
 
 static int fts_score_cmp(const uint32_t *uid, const struct fts_score_map *score)
diff -r d27b6724db32 -r 4dd97a92691a src/plugins/fts/fts-storage.h
--- a/src/plugins/fts/fts-storage.h	Mon Mar 12 13:17:50 2012 +0200
+++ b/src/plugins/fts/fts-storage.h	Mon Mar 12 13:45:19 2012 +0200
@@ -36,6 +36,7 @@
 
 	unsigned int virtual_mailbox:1;
 	unsigned int fts_lookup_success:1;
+	unsigned int indexing_timed_out:1;
 };
 
 /* Figure out if we want to use full text search indexes and update


More information about the dovecot-cvs mailing list