]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
stats: Fixes to handling per-command stats updates.
authorTimo Sirainen <tss@iki.fi>
Sat, 10 Mar 2012 13:53:39 +0000 (15:53 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 10 Mar 2012 13:53:39 +0000 (15:53 +0200)
src/plugins/imap-stats/imap-stats-plugin.c
src/stats/mail-command.c

index e1a1dc3f3a8e25f4e04ef98fb24332bffe27f122..9cb89a51cec2a3a4bdf81c822ca007172188a756 100644 (file)
@@ -56,7 +56,6 @@ static void stats_command_post(struct client_command_context *cmd)
        struct mail_stats stats, pre_trans_stats, trans_stats;
        unsigned int args_pos = 0;
        string_t *str;
-       bool done;
 
        if (scmd == NULL)
                return;
@@ -76,11 +75,13 @@ static void stats_command_post(struct client_command_context *cmd)
        str_append(str, "UPDATE-CMD\t");
        str_append(str, guid_128_to_string(suser->session_guid));
 
-       done = cmd->state == CLIENT_COMMAND_STATE_DONE;
-       str_printfa(str, "\t%u\t%d\t", scmd->id, done);
+       str_printfa(str, "\t%u\t", scmd->id);
+       if (cmd->state == CLIENT_COMMAND_STATE_DONE)
+               str_append_c(str, 'd');
        if (scmd->continued)
-               str_append_c(str, '\t');
+               str_append_c(str, 'c');
        else {
+               str_append_c(str, '\t');
                str_append(str, cmd->name);
                str_append_c(str, '\t');
                args_pos = str_len(str);
index 61269e12a5428d0aea18b094d0c60b303d9947a5..343823f10c12410e4e68cc02ad82fba741eae07e 100644 (file)
@@ -100,11 +100,12 @@ int mail_command_update_parse(const char *const *args, const char **error_r)
        struct mail_command *cmd;
        struct mail_stats stats, diff_stats;
        const char *error;
-       unsigned int cmd_id;
-       bool done;
+       unsigned int i, cmd_id;
+       bool done = FALSE, continued = FALSE;
 
-       /* <session guid> <cmd id> <done> <name> <args> [key=value ..] */
-       if (str_array_length(args) < 4) {
+       /* <session guid> <cmd id> [d] <name> <args> [key=value ..]
+          <session guid> <cmd id> c[d] [key=value ..] */
+       if (str_array_length(args) < 3) {
                *error_r = "UPDATE-CMD: Too few parameters";
                return -1;
        }
@@ -115,38 +116,62 @@ int mail_command_update_parse(const char *const *args, const char **error_r)
                *error_r = "UPDATE-CMD: Invalid command id";
                return -1;
        }
-       if (strcmp(args[2], "0") != 0 &&
-           strcmp(args[2], "1") != 0) {
-               *error_r = "UPDATE-CMD: Invalid done parameter";
-               return -1;
-       }
-       done = args[2][0] == '1';
-       if (mail_stats_parse(args+5, &stats, error_r) < 0) {
-               *error_r = t_strconcat("UPDATE-CMD: ", *error_r, NULL);
-               return -1;
+       for (i = 0; args[2][i] != '\0'; i++) {
+               switch (args[2][i]) {
+               case 'd':
+                       done = TRUE;
+                       break;
+               case 'c':
+                       continued = TRUE;
+                       break;
+               default:
+                       *error_r = "UPDATE-CMD: Invalid flags parameter";
+                       return -1;
+               }
        }
 
        cmd = mail_command_find(session, cmd_id);
-       if (cmd == NULL) {
+       if (!continued) {
+               /* new command */
+               if (cmd != NULL) {
+                       *error_r = "UPDATE-CMD: Duplicate new command id";
+                       return -1;
+               }
+               if (str_array_length(args) < 5) {
+                       *error_r = "UPDATE-CMD: Too few parameters";
+                       return -1;
+               }
                cmd = mail_command_add(session, args[3], args[4]);
                cmd->id = cmd_id;
-               cmd->stats = stats;
 
+               session->highest_cmd_id =
+                       I_MAX(session->highest_cmd_id, cmd_id);
                session->num_cmds++;
                session->user->num_cmds++;
                session->user->domain->num_cmds++;
                if (session->ip != NULL)
                        session->ip->num_cmds++;
+               args += 5;
        } else {
-               if (!mail_stats_diff(&cmd->stats, &stats, &diff_stats,
-                                    &error)) {
-                       *error_r = t_strconcat("UPDATE-CMD: stats shrank: ",
-                                              error, NULL);
-                       return -1;
+               if (cmd == NULL) {
+                       /* already expired command, ignore */
+                       i_warning("UPDATE-CMD: Already expired");
+                       return 0;
                }
+               args += 3;
                cmd->last_update = ioloop_timeval;
-               mail_stats_add(&cmd->stats, &diff_stats);
        }
+       if (mail_stats_parse(args, &stats, error_r) < 0) {
+               *error_r = t_strconcat("UPDATE-CMD: ", *error_r, NULL);
+               return -1;
+       }
+       if (!mail_stats_diff(&cmd->stats, &stats, &diff_stats, &error)) {
+               *error_r = t_strconcat("UPDATE-CMD: stats shrank: ",
+                                      error, NULL);
+               return -1;
+       }
+       mail_stats_add(&cmd->stats, &diff_stats);
+
        if (done) {
                cmd->id = 0;
                mail_command_unref(&cmd);