dovecot-2.1: stats: Update stats once per second for long runnin...

dovecot at dovecot.org dovecot at dovecot.org
Mon Mar 5 18:10:06 EET 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/d66568d34e40
changeset: 14257:d66568d34e40
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Mar 05 18:09:45 2012 +0200
description:
stats: Update stats once per second for long running nonblocking searches.

diffstat:

 src/plugins/stats/stats-plugin.c |  164 ++++++++++++++++++++++----------------
 src/plugins/stats/stats-plugin.h |    1 +
 2 files changed, 94 insertions(+), 71 deletions(-)

diffs (199 lines):

diff -r 817ef4c9f1f3 -r d66568d34e40 src/plugins/stats/stats-plugin.c
--- a/src/plugins/stats/stats-plugin.c	Mon Mar 05 17:28:06 2012 +0200
+++ b/src/plugins/stats/stats-plugin.c	Mon Mar 05 18:09:45 2012 +0200
@@ -165,77 +165,6 @@
 	user_trans_stats_get(suser, &stats_r->trans_stats);
 }
 
-static struct mailbox_transaction_context *
-stats_transaction_begin(struct mailbox *box,
-			enum mailbox_transaction_flags flags)
-{
-	struct stats_user *suser = STATS_USER_CONTEXT(box->storage->user);
-	struct stats_mailbox *sbox = STATS_CONTEXT(box);
-	struct mailbox_transaction_context *trans;
-	struct stats_transaction_context *strans;
-
-	trans = sbox->module_ctx.super.transaction_begin(box, flags);
-	trans->stats_track = TRUE;
-
-	strans = i_new(struct stats_transaction_context, 1);
-	strans->trans = trans;
-	DLLIST_PREPEND(&suser->transactions, strans);
-
-	MODULE_CONTEXT_SET(trans, stats_storage_module, strans);
-	return trans;
-}
-
-static void stats_transaction_free(struct stats_user *suser,
-				   struct stats_transaction_context *strans)
-{
-	DLLIST_REMOVE(&suser->transactions, strans);
-
-	trans_stats_add(&suser->session_stats.trans_stats,
-			&strans->trans->stats);
-}
-
-static int
-stats_transaction_commit(struct mailbox_transaction_context *ctx,
-			 struct mail_transaction_commit_changes *changes_r)
-{
-	struct stats_transaction_context *strans = STATS_CONTEXT(ctx);
-	struct stats_mailbox *sbox = STATS_CONTEXT(ctx->box);
-	struct stats_user *suser = STATS_USER_CONTEXT(ctx->box->storage->user);
-
-	stats_transaction_free(suser, strans);
-	return sbox->module_ctx.super.transaction_commit(ctx, changes_r);
-}
-
-static void
-stats_transaction_rollback(struct mailbox_transaction_context *ctx)
-{
-	struct stats_transaction_context *strans = STATS_CONTEXT(ctx);
-	struct stats_mailbox *sbox = STATS_CONTEXT(ctx->box);
-	struct stats_user *suser = STATS_USER_CONTEXT(ctx->box->storage->user);
-
-	stats_transaction_free(suser, strans);
-	sbox->module_ctx.super.transaction_rollback(ctx);
-}
-
-static void stats_mailbox_allocated(struct mailbox *box)
-{
-	struct mailbox_vfuncs *v = box->vlast;
-	struct stats_mailbox *sbox;
-	struct stats_user *suser = STATS_USER_CONTEXT(box->storage->user);
-
-	if (suser == NULL)
-		return;
-
-	sbox = p_new(box->pool, struct stats_mailbox, 1);
-	sbox->module_ctx.super = *v;
-	box->vlast = &sbox->module_ctx.super;
-
-	v->transaction_begin = stats_transaction_begin;
-	v->transaction_commit = stats_transaction_commit;
-	v->transaction_rollback = stats_transaction_rollback;
-	MODULE_CONTEXT_SET(box, stats_storage_module, sbox);
-}
-
 static void stats_io_activate(void *context)
 {
 	struct mail_user *user = context;
@@ -398,6 +327,7 @@
 	bool changed;
 
 	if (session_stats_need_send(suser, &changed, &to_next_secs)) {
+		suser->last_refresh = time(NULL);
 		suser->session_sent_duplicate = !changed;
 		suser->last_session_update = ioloop_time;
 		suser->last_sent_session_stats = suser->session_stats;
@@ -412,6 +342,98 @@
 			    session_stats_refresh_timeout, user);
 }
 
+static struct mailbox_transaction_context *
+stats_transaction_begin(struct mailbox *box,
+			enum mailbox_transaction_flags flags)
+{
+	struct stats_user *suser = STATS_USER_CONTEXT(box->storage->user);
+	struct stats_mailbox *sbox = STATS_CONTEXT(box);
+	struct mailbox_transaction_context *trans;
+	struct stats_transaction_context *strans;
+
+	trans = sbox->module_ctx.super.transaction_begin(box, flags);
+	trans->stats_track = TRUE;
+
+	strans = i_new(struct stats_transaction_context, 1);
+	strans->trans = trans;
+	DLLIST_PREPEND(&suser->transactions, strans);
+
+	MODULE_CONTEXT_SET(trans, stats_storage_module, strans);
+	return trans;
+}
+
+static void stats_transaction_free(struct stats_user *suser,
+				   struct stats_transaction_context *strans)
+{
+	DLLIST_REMOVE(&suser->transactions, strans);
+
+	trans_stats_add(&suser->session_stats.trans_stats,
+			&strans->trans->stats);
+}
+
+static int
+stats_transaction_commit(struct mailbox_transaction_context *ctx,
+			 struct mail_transaction_commit_changes *changes_r)
+{
+	struct stats_transaction_context *strans = STATS_CONTEXT(ctx);
+	struct stats_mailbox *sbox = STATS_CONTEXT(ctx->box);
+	struct stats_user *suser = STATS_USER_CONTEXT(ctx->box->storage->user);
+
+	stats_transaction_free(suser, strans);
+	return sbox->module_ctx.super.transaction_commit(ctx, changes_r);
+}
+
+static void
+stats_transaction_rollback(struct mailbox_transaction_context *ctx)
+{
+	struct stats_transaction_context *strans = STATS_CONTEXT(ctx);
+	struct stats_mailbox *sbox = STATS_CONTEXT(ctx->box);
+	struct stats_user *suser = STATS_USER_CONTEXT(ctx->box->storage->user);
+
+	stats_transaction_free(suser, strans);
+	sbox->module_ctx.super.transaction_rollback(ctx);
+}
+
+static bool stats_search_next_nonblock(struct mail_search_context *ctx,
+				       struct mail **mail_r, bool *tryagain_r)
+{
+	struct stats_mailbox *sbox = STATS_CONTEXT(ctx->transaction->box);
+	struct mail_user *user = ctx->transaction->box->storage->user;
+	struct stats_user *suser = STATS_USER_CONTEXT(user);
+	bool ret;
+
+	ret = sbox->module_ctx.super.
+		search_next_nonblock(ctx, mail_r, tryagain_r);
+	if (ret || !*tryagain_r)
+		return ret;
+
+	/* retrying, so this is a long running search. update the stats once
+	   a second */
+	if (time(NULL) != suser->last_refresh)
+		session_stats_refresh(user);
+	return FALSE;
+}
+
+static void stats_mailbox_allocated(struct mailbox *box)
+{
+	struct mailbox_vfuncs *v = box->vlast;
+	struct stats_mailbox *sbox;
+	struct stats_user *suser = STATS_USER_CONTEXT(box->storage->user);
+
+	if (suser == NULL)
+		return;
+
+	sbox = p_new(box->pool, struct stats_mailbox, 1);
+	sbox->module_ctx.super = *v;
+	box->vlast = &sbox->module_ctx.super;
+
+	v->transaction_begin = stats_transaction_begin;
+	v->transaction_commit = stats_transaction_commit;
+	v->transaction_rollback = stats_transaction_rollback;
+	v->search_next_nonblock = stats_search_next_nonblock;
+	MODULE_CONTEXT_SET(box, stats_storage_module, sbox);
+}
+
 static void session_stats_refresh_timeout(struct mail_user *user)
 {
 	if (stats_global_user != NULL)
diff -r 817ef4c9f1f3 -r d66568d34e40 src/plugins/stats/stats-plugin.h
--- a/src/plugins/stats/stats-plugin.h	Mon Mar 05 17:28:06 2012 +0200
+++ b/src/plugins/stats/stats-plugin.h	Mon Mar 05 18:09:45 2012 +0200
@@ -31,6 +31,7 @@
 	struct stats_connection *stats_conn;
 	guid_128_t session_guid;
 
+	time_t last_refresh;
 	unsigned int refresh_secs;
 	bool track_commands;
 


More information about the dovecot-cvs mailing list