dovecot-2.2: fts: Added fts_index_timeout setting to abort searc...
dovecot at dovecot.org
dovecot at dovecot.org
Sun May 20 03:26:27 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/4dd97a92691a
changeset: 14327: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