# HG changeset patch # User Timo Sirainen # Date 1271757408 -10800 # Node ID 0dca2668004f4fd344d7bb50950044666d036c2a # Parent e4c096fae5ac0be7c886992786fd6c599ee7fcc7 dict proxy: Disconnect from dict server after 1 second of idling. diff -r e4c096fae5ac -r 0dca2668004f src/lib-dict/dict-client.c --- a/src/lib-dict/dict-client.c Fri Apr 16 13:22:00 2010 +0300 +++ b/src/lib-dict/dict-client.c Tue Apr 20 12:56:48 2010 +0300 @@ -13,6 +13,12 @@ #include #include +/* Disconnect from dict server after this many milliseconds of idling after + sending a command. This timeout is short, because dict server does blocking + dict accesses, so it can handle only one client at a time. increasing the + timeout increases number of idling dict processes. */ +#define DICT_CLIENT_TIMEOUT_MSECS 1000 + struct client_dict { struct dict dict; @@ -27,6 +33,7 @@ struct istream *input; struct ostream *output; struct io *io; + struct timeout *to_idle; struct client_dict_transaction_context *transactions; @@ -308,12 +315,36 @@ return 1; } +static bool client_dict_is_finished(struct client_dict *dict) +{ + return dict->transactions == NULL && !dict->in_iteration && + dict->async_commits == 0; +} + +static void client_dict_timeout(struct client_dict *dict) +{ + if (client_dict_is_finished(dict)) + client_dict_disconnect(dict); +} + +static void client_dict_add_timeout(struct client_dict *dict) +{ + if (dict->to_idle != NULL) + timeout_reset(dict->to_idle); + else if (client_dict_is_finished(dict)) { + dict->to_idle = timeout_add(DICT_CLIENT_TIMEOUT_MSECS, + client_dict_timeout, dict); + } +} + static char *client_dict_read_line(struct client_dict *dict) { char *line; while (client_dict_read_one_line(dict, &line) == 0) ; + + client_dict_add_timeout(dict); return line; } @@ -363,6 +394,8 @@ dict->connect_counter++; dict->handshaked = FALSE; + if (dict->to_idle != NULL) + timeout_remove(&dict->to_idle); if (dict->io != NULL) io_remove(&dict->io); if (dict->input != NULL) @@ -542,6 +575,8 @@ pool_unref(&ctx->pool); i_free(ctx); dict->in_iteration = FALSE; + + client_dict_add_timeout(dict); } static struct dict_transaction_context * @@ -619,6 +654,8 @@ if (ret < 0 || !async) { DLLIST_REMOVE(&dict->transactions, ctx); i_free(ctx); + + client_dict_add_timeout(dict); } return ret; } @@ -640,6 +677,8 @@ DLLIST_REMOVE(&dict->transactions, ctx); i_free(ctx); + + client_dict_add_timeout(dict); } static void client_dict_set(struct dict_transaction_context *_ctx,