diff --git a/modules/ndb_redis/doc/ndb_redis.xml b/modules/ndb_redis/doc/ndb_redis.xml index cd1d752b944..d674217b511 100644 --- a/modules/ndb_redis/doc/ndb_redis.xml +++ b/modules/ndb_redis/doc/ndb_redis.xml @@ -9,38 +9,43 @@ ]> - - NDB_REDIS Module - sip-router.org - - - Daniel-Constantin - Mierla - miconda@gmail.com - - - Daniel-Constantin - Mierla - miconda@gmail.com - - - Vicente - Hernando - vhernando@systemonenoc.com - - - - 2011 - asipto.com - - - 2012 - www.systemonenoc.com - - - - - - - + + NDB_REDIS Module + sip-router.org + + + Daniel-Constantin + Mierla + miconda@gmail.com + + + Daniel-Constantin + Mierla + miconda@gmail.com + + + Vicente + Hernando + vhernando@systemonenoc.com + + + Morten + Isaksen + misak@uni-tel.dk + + + + 2011 + asipto.com + + + 2012 + www.systemonenoc.com + + + + + + + diff --git a/modules/ndb_redis/doc/ndb_redis_admin.xml b/modules/ndb_redis/doc/ndb_redis_admin.xml index b5e47d99aab..4e3975e56a0 100644 --- a/modules/ndb_redis/doc/ndb_redis_admin.xml +++ b/modules/ndb_redis/doc/ndb_redis_admin.xml @@ -10,9 +10,9 @@ - + &adminguide; - +
Overview @@ -108,6 +108,46 @@ modparam("ndb_redis", "server", "name=srvY;unix=/tmp/redis.sock;db=3") ... modparam("ndb_redis", "init_without_redis", 1) +... + + +
+
+ <varname>connect_timeout</varname> (int) + + The timeout when connecting to the redis server + + + + Default value is 1000 ms. + + + + Set <varname>connect_timeout</varname> parameter + +... +modparam("ndb_redis", "connect_timeout", 500) +... + + +
+
+ <varname>cmd_timeout</varname> (int) + + The timeout for each query to the redis server. If the redis server does + not reply within the timeout value, the command will fail and kamailio will + continue executing the cfg file. + + + + Default value is 1000 ms. + + + + Set <varname>cmd_timeout</varname> parameter + +... +modparam("ndb_redis", "cmd_timeout", 500) ... @@ -117,10 +157,10 @@ modparam("ndb_redis", "init_without_redis", 1)
Functions
- + <title> <function moreinfo="none">redis_cmd(srvname, command, ..., replyid)</function> - - + + Send a command to REDIS server identified by srvname. The reply will be stored in a local container identified by replyid. All the parameters can be strings with pseudo-variables that are evaluated @@ -194,7 +234,7 @@ if(redis_cmd("srvN", "HMGET foo_key field1 field3", "r")) { } ... - +
diff --git a/modules/ndb_redis/ndb_redis_mod.c b/modules/ndb_redis/ndb_redis_mod.c index c3c71f6232e..8e4f6b8b016 100644 --- a/modules/ndb_redis/ndb_redis_mod.c +++ b/modules/ndb_redis/ndb_redis_mod.c @@ -43,6 +43,8 @@ MODULE_VERSION int redis_srv_param(modparam_t type, void *val); int init_without_redis = 0; +int redis_connect_timeout_param = 1000; +int redis_cmd_timeout_param = 1000; static int w_redis_cmd3(struct sip_msg* msg, char* ssrv, char* scmd, char* sres); @@ -87,6 +89,8 @@ static cmd_export_t cmds[]={ static param_export_t params[]={ {"server", PARAM_STRING|USE_FUNC_PARAM, (void*)redis_srv_param}, {"init_without_redis", INT_PARAM, &init_without_redis}, + {"connect_timeout", INT_PARAM, &redis_connect_timeout_param}, + {"cmd_timeout", INT_PARAM, &redis_cmd_timeout_param}, {0, 0, 0} }; @@ -114,10 +118,9 @@ static int child_init(int rank) if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN) return 0; - if(redisc_init()<0) - { - LM_ERR("failed to initialize redis connections\n"); - return -1; + if(redisc_init()<0) { + LM_ERR("failed to initialize redis connections\n"); + return -1; } return 0; } @@ -553,7 +556,7 @@ static int pv_get_redisc(struct sip_msg *msg, pv_param_t *param, if(pos!=-1) return pv_get_null(msg, param, res); return pv_get_sintval(msg, param, res, - (int)rpv->reply->rplRedis->integer); + (int)rpv->reply->rplRedis->integer); case REDIS_REPLY_ARRAY: if(pos<0 || pos>=(int)rpv->reply->rplRedis->elements) return pv_get_null(msg, param, res); @@ -566,7 +569,7 @@ static int pv_get_redisc(struct sip_msg *msg, pv_param_t *param, return pv_get_strval(msg, param, res, &s); case REDIS_REPLY_INTEGER: return pv_get_sintval(msg, param, res, - (int)rpv->reply->rplRedis->element[pos]->integer); + (int)rpv->reply->rplRedis->element[pos]->integer); default: return pv_get_null(msg, param, res); } @@ -583,7 +586,8 @@ static int pv_get_redisc(struct sip_msg *msg, pv_param_t *param, case 3: /* size */ if(rpv->reply->rplRedis->type == REDIS_REPLY_ARRAY) { - return pv_get_uintval(msg, param, res, (unsigned int)rpv->reply->rplRedis->elements); + return pv_get_uintval(msg, param, res, + (unsigned int)rpv->reply->rplRedis->elements); } else { return pv_get_null(msg, param, res); } @@ -591,14 +595,15 @@ static int pv_get_redisc(struct sip_msg *msg, pv_param_t *param, /* type */ if(pos==-1) return pv_get_sintval(msg, param, res, - rpv->reply->rplRedis->type); + rpv->reply->rplRedis->type); if(rpv->reply->rplRedis->type != REDIS_REPLY_ARRAY) return pv_get_null(msg, param, res); if(pos<0 || pos>=(int)rpv->reply->rplRedis->elements) return pv_get_null(msg, param, res); if(rpv->reply->rplRedis->element[pos]==NULL) return pv_get_null(msg, param, res); - return pv_get_sintval(msg, param, res, rpv->reply->rplRedis->element[pos]->type); + return pv_get_sintval(msg, param, res, + rpv->reply->rplRedis->element[pos]->type); default: /* We do nothing. */ return pv_get_null(msg, param, res); diff --git a/modules/ndb_redis/redis_client.c b/modules/ndb_redis/redis_client.c index 903284e5b20..dff2ef208c0 100644 --- a/modules/ndb_redis/redis_client.c +++ b/modules/ndb_redis/redis_client.c @@ -42,6 +42,9 @@ static redisc_server_t *_redisc_srv_list=NULL; static redisc_reply_t *_redisc_rpl_list=NULL; extern int init_without_redis; +extern int redis_connect_timeout_param; +extern int redis_cmd_timeout_param; + /** * @@ -52,10 +55,14 @@ int redisc_init(void) unsigned int port, db; redisc_server_t *rsrv=NULL; param_t *pit = NULL; - struct timeval tv; + struct timeval tv_conn; + struct timeval tv_cmd; + + tv_conn.tv_sec = (int) redis_connect_timeout_param / 1000; + tv_conn.tv_usec = (int) (redis_connect_timeout_param % 1000) * 1000; - tv.tv_sec = 1; - tv.tv_usec = 0; + tv_cmd.tv_sec = (int) redis_cmd_timeout_param / 1000; + tv_cmd.tv_usec = (int) (redis_cmd_timeout_param % 1000) * 1000; if(_redisc_srv_list==NULL) { @@ -92,9 +99,9 @@ int redisc_init(void) if(unix_sock_path != NULL) { LM_DBG("Connecting to unix socket: %s\n", unix_sock_path); - rsrv->ctxRedis = redisConnectUnixWithTimeout(unix_sock_path, tv); + rsrv->ctxRedis = redisConnectUnixWithTimeout(unix_sock_path, tv_conn); } else { - rsrv->ctxRedis = redisConnectWithTimeout(addr, port, tv); + rsrv->ctxRedis = redisConnectWithTimeout(addr, port, tv_conn); } if(!rsrv->ctxRedis) @@ -103,6 +110,8 @@ int redisc_init(void) goto err2; if ((pass != NULL) && redisc_check_auth(rsrv, pass)) goto err2; + if (redisSetTimeout(rsrv->ctxRedis, tv_cmd)) + goto err2; if (redisCommandNR(rsrv->ctxRedis, "PING")) goto err2; if (redisCommandNR(rsrv->ctxRedis, "SELECT %i", db)) @@ -115,10 +124,10 @@ int redisc_init(void) err2: if (unix_sock_path != NULL) { LM_ERR("error communicating with redis server [%.*s] (unix:%s db:%d): %s\n", - rsrv->sname->len, rsrv->sname->s, unix_sock_path, db, rsrv->ctxRedis->errstr); + rsrv->sname->len, rsrv->sname->s, unix_sock_path, db, rsrv->ctxRedis->errstr); } else { LM_ERR("error communicating with redis server [%.*s] (%s:%d/%d): %s\n", - rsrv->sname->len, rsrv->sname->s, addr, port, db, rsrv->ctxRedis->errstr); + rsrv->sname->len, rsrv->sname->s, addr, port, db, rsrv->ctxRedis->errstr); } if (init_without_redis==1) { @@ -130,10 +139,10 @@ int redisc_init(void) err: if (unix_sock_path != NULL) { LM_ERR("failed to connect to redis server [%.*s] (unix:%s db:%d)\n", - rsrv->sname->len, rsrv->sname->s, unix_sock_path, db); + rsrv->sname->len, rsrv->sname->s, unix_sock_path, db); } else { LM_ERR("failed to connect to redis server [%.*s] (%s:%d/%d)\n", - rsrv->sname->len, rsrv->sname->s, addr, port, db); + rsrv->sname->len, rsrv->sname->s, addr, port, db); } if (init_without_redis==1) { @@ -266,10 +275,15 @@ int redisc_reconnect_server(redisc_server_t *rsrv) char *addr, *pass, *unix_sock_path = NULL; unsigned int port, db; param_t *pit = NULL; - struct timeval tv; + struct timeval tv_conn; + struct timeval tv_cmd; + + tv_conn.tv_sec = (int) redis_connect_timeout_param / 1000; + tv_conn.tv_usec = (int) (redis_connect_timeout_param % 1000) * 1000; + + tv_cmd.tv_sec = (int) redis_cmd_timeout_param / 1000; + tv_cmd.tv_usec = (int) (redis_cmd_timeout_param % 1000) * 1000; - tv.tv_sec = 1; - tv.tv_usec = 0; addr = "127.0.0.1"; port = 6379; db = 0; @@ -299,9 +313,9 @@ int redisc_reconnect_server(redisc_server_t *rsrv) } if(unix_sock_path != NULL) { - rsrv->ctxRedis = redisConnectUnixWithTimeout(unix_sock_path, tv); + rsrv->ctxRedis = redisConnectUnixWithTimeout(unix_sock_path, tv_conn); } else { - rsrv->ctxRedis = redisConnectWithTimeout(addr, port, tv); + rsrv->ctxRedis = redisConnectWithTimeout(addr, port, tv_conn); } if(!rsrv->ctxRedis) goto err; @@ -309,6 +323,8 @@ int redisc_reconnect_server(redisc_server_t *rsrv) goto err2; if ((pass != NULL) && redisc_check_auth(rsrv, pass)) goto err2; + if (redisSetTimeout(rsrv->ctxRedis, tv_cmd)) + goto err2; if (redisCommandNR(rsrv->ctxRedis, "PING")) goto err2; if (redisCommandNR(rsrv->ctxRedis, "SELECT %i", db)) @@ -319,18 +335,18 @@ int redisc_reconnect_server(redisc_server_t *rsrv) err2: if (unix_sock_path != NULL) { LM_ERR("error communicating with redis server [%.*s] (unix:%s db:%d): %s\n", - rsrv->sname->len, rsrv->sname->s, unix_sock_path, db, rsrv->ctxRedis->errstr); + rsrv->sname->len, rsrv->sname->s, unix_sock_path, db, rsrv->ctxRedis->errstr); } else { LM_ERR("error communicating with redis server [%.*s] (%s:%d/%d): %s\n", - rsrv->sname->len, rsrv->sname->s, addr, port, db, rsrv->ctxRedis->errstr); + rsrv->sname->len, rsrv->sname->s, addr, port, db, rsrv->ctxRedis->errstr); } err: if (unix_sock_path != NULL) { LM_ERR("failed to connect to redis server [%.*s] (unix:%s db:%d)\n", - rsrv->sname->len, rsrv->sname->s, unix_sock_path, db); + rsrv->sname->len, rsrv->sname->s, unix_sock_path, db); } else { LM_ERR("failed to connect to redis server [%.*s] (%s:%d/%d)\n", - rsrv->sname->len, rsrv->sname->s, addr, port, db); + rsrv->sname->len, rsrv->sname->s, addr, port, db); } return -1; } @@ -429,8 +445,8 @@ void * redisc_exec_argv(redisc_server_t *rsrv, int argc, const char **argv, cons if(rsrv==NULL || rsrv->ctxRedis==NULL) { LM_ERR("no redis context found for server %.*s\n", - (rsrv)?rsrv->sname->len:0, - (rsrv)?rsrv->sname->s:""); + (rsrv)?rsrv->sname->len:0, + (rsrv)?rsrv->sname->s:""); return NULL; } if(argc<=0) @@ -461,7 +477,7 @@ void * redisc_exec_argv(redisc_server_t *rsrv, int argc, const char **argv, cons else { LM_ERR("Unable to reconnect to server: %.*s\n", - rsrv->sname->len, rsrv->sname->s); + rsrv->sname->len, rsrv->sname->s); return NULL; } @@ -528,7 +544,7 @@ int redisc_free_reply(str *name) while(rpl) { if(rpl->hname==hid && rpl->rname.len==name->len - && strncmp(rpl->rname.s, name->s, name->len)==0) { + && strncmp(rpl->rname.s, name->s, name->len)==0) { if(rpl->rplRedis) { freeReplyObject(rpl->rplRedis); rpl->rplRedis = NULL;