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