Browse Source

Add parameter that sets a timeout for redis commands

pull/445/head
Claudiu Boriga 8 years ago
parent
commit
562c5b40a6
4 changed files with 26 additions and 6 deletions
  1. +5
    -0
      README.md
  2. +7
    -3
      daemon/main.c
  3. +12
    -2
      daemon/redis.c
  4. +2
    -1
      daemon/redis.h

+ 5
- 0
README.md View File

@ -456,6 +456,11 @@ The options are described in more detail below.
This parameter configures the number of seconds redis communication is disabled because of errors. This parameter configures the number of seconds redis communication is disabled because of errors.
This works together with redis-allowed-errors parameter. The default value is 10. This works together with redis-allowed-errors parameter. The default value is 10.
* --redis-cmd-timeout
If this parameter is set to a non-zero value it will set the timeout, in milliseconds, for each command to the redis server.
If redis does not reply within the specified timeout the command will fail. The default value is 0, meaning that the commands
will have no timeout
* -b, --b2b-url * -b, --b2b-url
Enables and sets the URI for an XMLRPC callback to be made when a call is torn down due to packet Enables and sets the URI for an XMLRPC callback to be made when a call is torn down due to packet


+ 7
- 3
daemon/main.c View File

@ -73,6 +73,7 @@ static int redis_num_threads;
static int no_redis_required; static int no_redis_required;
static int redis_allowed_errors = -1; static int redis_allowed_errors = -1;
static int redis_disable_time = 10; static int redis_disable_time = 10;
static int redis_cmd_timeout = 0;
static char *redis_auth; static char *redis_auth;
static char *redis_write_auth; static char *redis_write_auth;
static char *b2b_url; static char *b2b_url;
@ -282,6 +283,7 @@ static void options(int *argc, char ***argv) {
{ "no-redis-required", 'q', 0, G_OPTION_ARG_NONE, &no_redis_required, "Start no matter of redis connection state", NULL }, { "no-redis-required", 'q', 0, G_OPTION_ARG_NONE, &no_redis_required, "Start no matter of redis connection state", NULL },
{ "redis-allowed-errors", 0, 0, G_OPTION_ARG_INT, &redis_allowed_errors, "Number of allowed errors before redis is temporarily disabled", "INT" }, { "redis-allowed-errors", 0, 0, G_OPTION_ARG_INT, &redis_allowed_errors, "Number of allowed errors before redis is temporarily disabled", "INT" },
{ "redis-disable-time", 0, 0, G_OPTION_ARG_INT, &redis_disable_time, "Number of seconds redis communication is disabled because of errors", "INT" }, { "redis-disable-time", 0, 0, G_OPTION_ARG_INT, &redis_disable_time, "Number of seconds redis communication is disabled because of errors", "INT" },
{ "redis-cmd-timeout", 0, 0, G_OPTION_ARG_INT, &redis_cmd_timeout, "Sets a timeout in milliseconds for redis commands", "INT" },
{ "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &b2b_url, "XMLRPC URL of B2B UA" , "STRING" }, { "b2b-url", 'b', 0, G_OPTION_ARG_STRING, &b2b_url, "XMLRPC URL of B2B UA" , "STRING" },
{ "log-facility-cdr",0, 0, G_OPTION_ARG_STRING, &log_facility_cdr_s, "Syslog facility to use for logging CDRs", "daemon|local0|...|local7"}, { "log-facility-cdr",0, 0, G_OPTION_ARG_STRING, &log_facility_cdr_s, "Syslog facility to use for logging CDRs", "daemon|local0|...|local7"},
{ "log-facility-rtcp",0, 0, G_OPTION_ARG_STRING, &log_facility_rtcp_s, "Syslog facility to use for logging RTCP", "daemon|local0|...|local7"}, { "log-facility-rtcp",0, 0, G_OPTION_ARG_STRING, &log_facility_rtcp_s, "Syslog facility to use for logging RTCP", "daemon|local0|...|local7"},
@ -582,7 +584,7 @@ no_kernel:
if (!is_addr_unspecified(&redis_write_ep.address)) { if (!is_addr_unspecified(&redis_write_ep.address)) {
mc.redis_write = redis_new(&redis_write_ep, redis_write_db, mc.redis_write = redis_new(&redis_write_ep, redis_write_db,
redis_write_auth, ANY_REDIS_ROLE, no_redis_required, redis_write_auth, ANY_REDIS_ROLE, no_redis_required,
redis_allowed_errors, redis_disable_time);
redis_allowed_errors, redis_disable_time, redis_cmd_timeout);
if (!mc.redis_write) if (!mc.redis_write)
die("Cannot start up without running Redis %s write database! See also NO_REDIS_REQUIRED parameter.", die("Cannot start up without running Redis %s write database! See also NO_REDIS_REQUIRED parameter.",
endpoint_print_buf(&redis_write_ep)); endpoint_print_buf(&redis_write_ep));
@ -591,10 +593,12 @@ no_kernel:
if (!is_addr_unspecified(&redis_ep.address)) { if (!is_addr_unspecified(&redis_ep.address)) {
mc.redis = redis_new(&redis_ep, redis_db, redis_auth, mc.redis = redis_new(&redis_ep, redis_db, redis_auth,
mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE,
no_redis_required, redis_allowed_errors, redis_disable_time);
no_redis_required, redis_allowed_errors, redis_disable_time,
redis_cmd_timeout);
mc.redis_notify = redis_new(&redis_ep, redis_db, redis_auth, mc.redis_notify = redis_new(&redis_ep, redis_db, redis_auth,
mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE,
no_redis_required, redis_allowed_errors, redis_disable_time);
no_redis_required, redis_allowed_errors, redis_disable_time,
redis_cmd_timeout);
if (!mc.redis || !mc.redis_notify) if (!mc.redis || !mc.redis_notify)
die("Cannot start up without running Redis %s database! See also NO_REDIS_REQUIRED parameter.", die("Cannot start up without running Redis %s database! See also NO_REDIS_REQUIRED parameter.",
endpoint_print_buf(&redis_ep)); endpoint_print_buf(&redis_ep));


+ 12
- 2
daemon/redis.c View File

@ -183,6 +183,15 @@ static int redis_connect(struct redis *r, int wait) {
if (r->ctx->err) if (r->ctx->err)
goto err2; goto err2;
if (r->cmd_timeout) {
struct timeval tv_cmd;
tv_cmd.tv_sec = (int) r->cmd_timeout / 1000;
tv_cmd.tv_usec = (int) (r->cmd_timeout % 1000) * 1000;
if (redisSetTimeout(r->ctx, tv_cmd))
goto err2;
ilog(LOG_INFO, "Setting timeout for Redis commands to %d milliseconds",r->cmd_timeout);
}
if (r->auth) { if (r->auth) {
if (redisCommandNR(r->ctx, "AUTH %s", r->auth)) if (redisCommandNR(r->ctx, "AUTH %s", r->auth))
goto err2; goto err2;
@ -630,7 +639,7 @@ void redis_notify_loop(void *d) {
struct redis *redis_new(const endpoint_t *ep, int db, const char *auth, struct redis *redis_new(const endpoint_t *ep, int db, const char *auth,
enum redis_role role, int no_redis_required, int redis_allowed_errors, enum redis_role role, int no_redis_required, int redis_allowed_errors,
int redis_disable_time) {
int redis_disable_time, int redis_cmd_timeout) {
struct redis *r; struct redis *r;
r = g_slice_alloc0(sizeof(*r)); r = g_slice_alloc0(sizeof(*r));
@ -645,6 +654,7 @@ struct redis *redis_new(const endpoint_t *ep, int db, const char *auth,
r->disable_time = redis_disable_time; r->disable_time = redis_disable_time;
r->restore_tick = 0; r->restore_tick = 0;
r->consecutive_errors = 0; r->consecutive_errors = 0;
r->cmd_timeout = redis_cmd_timeout;
mutex_init(&r->lock); mutex_init(&r->lock);
if (redis_connect(r, 10)) { if (redis_connect(r, 10)) {
@ -1686,7 +1696,7 @@ int redis_restore(struct callmaster *m, struct redis *r) {
g_queue_push_tail(&ctx.r_q, g_queue_push_tail(&ctx.r_q,
redis_new(&r->endpoint, r->db, r->auth, r->role, redis_new(&r->endpoint, r->db, r->auth, r->role,
r->no_redis_required, r->allowed_errors, r->no_redis_required, r->allowed_errors,
r->disable_time));
r->disable_time,r->cmd_timeout));
gtp = g_thread_pool_new(restore_thread, &ctx, m->conf.redis_num_threads, TRUE, NULL); gtp = g_thread_pool_new(restore_thread, &ctx, m->conf.redis_num_threads, TRUE, NULL);
for (i = 0; i < calls->elements; i++) { for (i = 0; i < calls->elements; i++) {


+ 2
- 1
daemon/redis.h View File

@ -65,6 +65,7 @@ struct redis {
int consecutive_errors; int consecutive_errors;
int disable_time; int disable_time;
time_t restore_tick; time_t restore_tick;
int cmd_timeout;
}; };
struct redis_hash { struct redis_hash {
@ -96,7 +97,7 @@ INLINE gboolean g_hash_table_insert_check(GHashTable *h, gpointer k, gpointer v)
void redis_notify_loop(void *d); void redis_notify_loop(void *d);
struct redis *redis_new(const endpoint_t *, int, const char *, enum redis_role, int, int, int);
struct redis *redis_new(const endpoint_t *, int, const char *, enum redis_role, int, int, int, int);
int redis_restore(struct callmaster *, struct redis *); int redis_restore(struct callmaster *, struct redis *);
void redis_update(struct call *, struct redis *); void redis_update(struct call *, struct redis *);
void redis_update_onekey(struct call *c, struct redis *r); void redis_update_onekey(struct call *c, struct redis *r);


Loading…
Cancel
Save