Skip to content

Commit

Permalink
dict: Show command statistics in process title.
Browse files Browse the repository at this point in the history
  • Loading branch information
sirainen committed May 25, 2016
1 parent b1d2b70 commit cbe49ba
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/dict/Makefile.am
Expand Up @@ -33,4 +33,5 @@ dict_SOURCES = \
noinst_HEADERS = \
dict-connection.h \
dict-commands.h \
dict-settings.h
dict-settings.h \
main.h
43 changes: 42 additions & 1 deletion src/dict/dict-commands.c
Expand Up @@ -5,11 +5,13 @@
#include "ostream.h"
#include "str.h"
#include "strescape.h"
#include "timing.h"
#include "time-util.h"
#include "dict-client.h"
#include "dict-settings.h"
#include "dict-connection.h"
#include "dict-commands.h"

#include "main.h"

#define DICT_OUTPUT_OPTIMAL_SIZE 1024

Expand All @@ -21,6 +23,7 @@ struct dict_cmd_func {
struct dict_connection_cmd {
const struct dict_cmd_func *cmd;
struct dict_connection *conn;
struct timeval start_timeval;
char *reply;

struct dict_iterate_context *iter;
Expand All @@ -29,6 +32,8 @@ struct dict_connection_cmd {
unsigned int trans_id;
};

struct dict_command_stats cmd_stats;

static void dict_connection_cmd_output_more(struct dict_connection_cmd *cmd);

static void dict_connection_cmd_free(struct dict_connection_cmd *cmd)
Expand Down Expand Up @@ -82,11 +87,29 @@ static void dict_connection_cmds_flush(struct dict_connection *conn)
dict_connection_unref_safe(conn);
}

static void
cmd_stats_update(struct dict_connection_cmd *cmd, struct timing *timing)
{
long long diff;

if (!dict_settings->verbose_proctitle)
return;

io_loop_time_refresh();
diff = timeval_diff_usecs(&ioloop_timeval, &cmd->start_timeval);
if (diff < 0)
diff = 0;
timing_add_usecs(timing, diff);
dict_proctitle_update_later();
}

static void
cmd_lookup_callback(const struct dict_lookup_result *result, void *context)
{
struct dict_connection_cmd *cmd = context;

cmd_stats_update(cmd, cmd_stats.lookups);

if (result->ret > 0) {
cmd->reply = i_strdup_printf("%c%s\n",
DICT_PROTOCOL_REPLY_OK, str_tabescape(result->value));
Expand Down Expand Up @@ -149,6 +172,7 @@ static int cmd_iterate_flush(struct dict_connection_cmd *cmd)
str_append_c(str, '\n');
o_stream_uncork(cmd->conn->output);

cmd_stats_update(cmd, cmd_stats.iterations);
cmd->reply = i_strdup(str_c(str));
dict_connection_cmds_flush(cmd->conn);
return 1;
Expand Down Expand Up @@ -267,6 +291,8 @@ cmd_commit_finish(struct dict_connection_cmd *cmd,
string_t *str = t_str_new(64);
char chr;

cmd_stats_update(cmd, cmd_stats.commits);

switch (result->ret) {
case 1:
chr = DICT_PROTOCOL_REPLY_OK;
Expand Down Expand Up @@ -444,6 +470,7 @@ int dict_command_input(struct dict_connection *conn, const char *line)
cmd = i_new(struct dict_connection_cmd, 1);
cmd->conn = conn;
cmd->cmd = cmd_func;
cmd->start_timeval = ioloop_timeval;
array_append(&conn->cmds, &cmd, 1);
dict_connection_ref(conn);
if ((ret = cmd_func->func(cmd, line + 1)) <= 0) {
Expand Down Expand Up @@ -481,3 +508,17 @@ void dict_connection_cmds_output_more(struct dict_connection *conn)
/* cmd should be freed now */
}
}

void dict_commands_init(void)
{
cmd_stats.lookups = timing_init();
cmd_stats.iterations = timing_init();
cmd_stats.commits = timing_init();
}

void dict_commands_deinit(void)
{
timing_deinit(&cmd_stats.lookups);
timing_deinit(&cmd_stats.iterations);
timing_deinit(&cmd_stats.commits);
}
11 changes: 11 additions & 0 deletions src/dict/dict-commands.h
Expand Up @@ -3,8 +3,19 @@

struct dict_connection;

struct dict_command_stats {
struct timing *lookups;
struct timing *iterations;
struct timing *commits;
};

extern struct dict_command_stats cmd_stats;

int dict_command_input(struct dict_connection *conn, const char *line);

void dict_connection_cmds_output_more(struct dict_connection *conn);

void dict_commands_init(void);
void dict_commands_deinit(void);

#endif
11 changes: 11 additions & 0 deletions src/dict/dict-connection.c
Expand Up @@ -17,6 +17,7 @@
#define DICT_CONN_MAX_PENDING_COMMANDS 5

static struct dict_connection *dict_connections;
static unsigned int dict_connections_count = 0;

static int dict_connection_parse_handshake(struct dict_connection *conn,
const char *line)
Expand Down Expand Up @@ -199,6 +200,8 @@ struct dict_connection *dict_connection_create(int fd)
o_stream_set_flush_callback(conn->output, dict_connection_output, conn);
conn->io = io_add(fd, IO_READ, dict_connection_input, conn);
i_array_init(&conn->cmds, DICT_CONN_MAX_PENDING_COMMANDS);

dict_connections_count++;
DLLIST_PREPEND(&dict_connections, conn);
return conn;
}
Expand Down Expand Up @@ -273,6 +276,9 @@ void dict_connection_destroy(struct dict_connection *conn)
i_assert(!conn->destroyed);
i_assert(conn->to_unref == NULL);

i_assert(dict_connections_count > 0);
dict_connections_count--;

conn->destroyed = TRUE;
DLLIST_REMOVE(&dict_connections, conn);

Expand All @@ -297,6 +303,11 @@ void dict_connection_destroy(struct dict_connection *conn)
dict_connection_unref(conn);
}

unsigned int dict_connections_current_count(void)
{
return dict_connections_count;
}

void dict_connections_destroy_all(void)
{
while (dict_connections != NULL)
Expand Down
1 change: 1 addition & 0 deletions src/dict/dict-connection.h
Expand Up @@ -43,6 +43,7 @@ void dict_connection_unref_safe(struct dict_connection *conn);

void dict_connection_continue_input(struct dict_connection *conn);

unsigned int dict_connections_current_count(void);
void dict_connections_destroy_all(void);

#endif
4 changes: 4 additions & 0 deletions src/dict/dict-settings.c
Expand Up @@ -86,6 +86,8 @@ struct service_settings dict_async_service_settings = {

static const struct setting_define dict_setting_defines[] = {
DEF(SET_STR, base_dir),
DEF(SET_BOOL, verbose_proctitle),

DEF(SET_STR, dict_db_config),
{ SET_STRLIST, "dict", offsetof(struct dict_server_settings, dicts), NULL },

Expand All @@ -94,6 +96,8 @@ static const struct setting_define dict_setting_defines[] = {

const struct dict_server_settings dict_default_settings = {
.base_dir = PKG_RUNDIR,
.verbose_proctitle = FALSE,

.dict_db_config = "",
.dicts = ARRAY_INIT
};
Expand Down
2 changes: 2 additions & 0 deletions src/dict/dict-settings.h
Expand Up @@ -3,6 +3,8 @@

struct dict_server_settings {
const char *base_dir;
bool verbose_proctitle;

const char *dict_db_config;
ARRAY(const char *) dicts;
};
Expand Down
56 changes: 54 additions & 2 deletions src/dict/main.c
Expand Up @@ -2,19 +2,67 @@

#include "lib.h"
#include "restrict-access.h"
#include "ioloop.h"
#include "randgen.h"
#include "str.h"
#include "hostpid.h"
#include "timing.h"
#include "process-title.h"
#include "env-util.h"
#include "module-dir.h"
#include "master-service.h"
#include "master-service-settings.h"
#include "sql-api.h"
#include "dict.h"
#include "dict-client.h"
#include "dict-commands.h"
#include "dict-connection.h"
#include "dict-settings.h"
#include "main.h"

static struct module *modules;
static struct timeout *to_proctitle;
static bool proctitle_updated;

static void
add_timing_string(string_t *str, struct timing *timing, const char *name)
{
str_printfa(str, ", %u %s:%llu/%llu/%llu/%llu",
timing_get_count(timing), name,
(unsigned long long)timing_get_min(timing)/1000,
(unsigned long long)timing_get_avg(timing)/1000,
(unsigned long long)timing_get_95th(timing)/1000,
(unsigned long long)timing_get_max(timing)/1000);
timing_reset(timing);
}

static void dict_proctitle_update(void *context ATTR_UNUSED)
{
string_t *str = t_str_new(128);

if (!proctitle_updated)
timeout_remove(&to_proctitle);

str_printfa(str, "[%u clients", dict_connections_current_count());

add_timing_string(str, cmd_stats.lookups, "lookups");
add_timing_string(str, cmd_stats.iterations, "iters");
add_timing_string(str, cmd_stats.commits, "commits");
str_append_c(str, ']');

process_title_set(str_c(str));
proctitle_updated = FALSE;
}

void dict_proctitle_update_later(void)
{
if (!dict_settings->verbose_proctitle)
return;

if (to_proctitle == NULL)
to_proctitle = timeout_add(1000, dict_proctitle_update, NULL);
proctitle_updated = TRUE;
}

static void dict_die(void)
{
Expand Down Expand Up @@ -68,12 +116,17 @@ static void main_init(void)
/* Register only after loading modules. They may contain SQL drivers,
which we'll need to register. */
dict_drivers_register_all();
dict_commands_init();
}

static void main_deinit(void)
{
if (to_proctitle != NULL)
timeout_remove(&to_proctitle);

dict_connections_destroy_all();
dict_drivers_unregister_all();
dict_commands_deinit();

module_dir_unload(&modules);

Expand All @@ -83,8 +136,7 @@ static void main_deinit(void)

int main(int argc, char *argv[])
{
const enum master_service_flags service_flags =
MASTER_SERVICE_FLAG_UPDATE_PROCTITLE;
const enum master_service_flags service_flags = 0;
const struct setting_parser_info *set_roots[] = {
&dict_setting_parser_info,
NULL
Expand Down

0 comments on commit cbe49ba

Please sign in to comment.