static int pv_get_redisc(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { redisc_pv_t *rpv; str s; int pos; rpv = (redisc_pv_t*)param->pvn.u.dname; if(rpv->reply==NULL) { rpv->reply = redisc_get_reply(&rpv->rname); if(rpv->reply==NULL) return pv_get_null(msg, param, res); } if(rpv->reply->rplRedis==NULL) return pv_get_null(msg, param, res); if(fixup_get_ivalue(msg, &rpv->pos, &pos)!=0) return pv_get_null(msg, param, res); switch(rpv->rkeyid) { case 1: /* value */ switch(rpv->reply->rplRedis->type) { case REDIS_REPLY_STRING: if(pos!=-1) return pv_get_null(msg, param, res); s.len = rpv->reply->rplRedis->len; s.s = rpv->reply->rplRedis->str; return pv_get_strval(msg, param, res, &s); case REDIS_REPLY_INTEGER: if(pos!=-1) return pv_get_null(msg, param, res); return pv_get_sintval(msg, param, res, (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); if(rpv->reply->rplRedis->element[pos]==NULL) return pv_get_null(msg, param, res); switch(rpv->reply->rplRedis->element[pos]->type) { case REDIS_REPLY_STRING: s.len = rpv->reply->rplRedis->element[pos]->len; s.s = rpv->reply->rplRedis->element[pos]->str; 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); default: return pv_get_null(msg, param, res); } default: return pv_get_null(msg, param, res); } case 2: /* info */ if(rpv->reply->rplRedis->str==NULL) return pv_get_null(msg, param, res); s.len = rpv->reply->rplRedis->len; s.s = rpv->reply->rplRedis->str; return pv_get_strval(msg, param, res, &s); case 3: /* size */ if(rpv->reply->rplRedis->type == REDIS_REPLY_ARRAY) { return pv_get_uintval(msg, param, res, (unsigned int)rpv->reply->rplRedis->elements); } else { return pv_get_null(msg, param, res); } case 0: /* type */ if(pos==-1) return pv_get_sintval(msg, param, res, 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); default: /* We do nothing. */ return pv_get_null(msg, param, res); } }
int redisc_exec(str *srv, str *res, str *cmd, ...) { redisc_server_t *rsrv=NULL; redisc_reply_t *rpl; char c; va_list ap, ap2, ap3, ap4; va_start(ap, cmd); va_copy(ap2, ap); va_copy(ap3, ap); va_copy(ap4, ap); if(srv==NULL || cmd==NULL || res==NULL) { LM_ERR("invalid parameters"); goto error_exec; } if(srv->len==0 || res->len==0 || cmd->len==0) { LM_ERR("invalid parameters"); goto error_exec; } rsrv = redisc_get_server(srv); if(rsrv==NULL) { LM_ERR("no redis server found: %.*s\n", srv->len, srv->s); goto error_exec; } LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); if(rsrv->ctxRedis==NULL) { LM_ERR("no redis context for server: %.*s\n", srv->len, srv->s); goto error_exec; } LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); if (rsrv->piped.pending_commands != 0) { LM_NOTICE("Calling redis_cmd with pipelined commands in the buffer. Automatically call redis_execute"); redisc_exec_pipelined(rsrv); } /* if server is disabled do nothing unless the disable time has passed */ if (redis_check_server(rsrv)) { goto srv_disabled; } rpl = redisc_get_reply(res); if(rpl==NULL) { LM_ERR("no redis reply id found: %.*s\n", res->len, res->s); goto error_exec; } c = cmd->s[cmd->len]; cmd->s[cmd->len] = '\0'; if(rpl->rplRedis!=NULL) { /* clean up previous redis reply */ freeReplyObject(rpl->rplRedis); rpl->rplRedis = NULL; } rpl->rplRedis = redisvCommand(rsrv->ctxRedis, cmd->s, ap ); if(rpl->rplRedis == NULL) { /* null reply, reconnect and try again */ if(rsrv->ctxRedis->err) { LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr); } if(redisc_reconnect_server(rsrv)==0) { rpl->rplRedis = redisvCommand(rsrv->ctxRedis, cmd->s, ap2); if (rpl->rplRedis ==NULL) { redis_count_err_and_disable(rsrv); goto error_exec; } } else { redis_count_err_and_disable(rsrv); LM_ERR("unable to reconnect to redis server: %.*s\n", srv->len, srv->s); cmd->s[cmd->len] = c; goto error_exec; } } if (check_cluster_reply(rpl->rplRedis, &rsrv)) { LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); if(rsrv->ctxRedis==NULL) { LM_ERR("no redis context for server: %.*s\n", srv->len, srv->s); goto error_exec; } LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); if(rpl->rplRedis!=NULL) { /* clean up previous redis reply */ freeReplyObject(rpl->rplRedis); rpl->rplRedis = NULL; } rpl->rplRedis = redisvCommand(rsrv->ctxRedis, cmd->s, ap3 ); if(rpl->rplRedis == NULL) { /* null reply, reconnect and try again */ if(rsrv->ctxRedis->err) { LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr); } if(redisc_reconnect_server(rsrv)==0) { rpl->rplRedis = redisvCommand(rsrv->ctxRedis, cmd->s, ap4); } else { LM_ERR("unable to reconnect to redis server: %.*s\n", srv->len, srv->s); cmd->s[cmd->len] = c; goto error_exec; } } } cmd->s[cmd->len] = c; rsrv->disable.consecutive_errors = 0; va_end(ap); va_end(ap2); va_end(ap3); va_end(ap4); LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); return 0; error_exec: va_end(ap); va_end(ap2); va_end(ap3); va_end(ap4); return -1; srv_disabled: va_end(ap); va_end(ap2); va_end(ap3); va_end(ap4); return -2; }
int redisc_exec(str *srv, str *res, str *cmd, ...) { redisc_server_t *rsrv=NULL; redisc_reply_t *rpl; char c; va_list ap; va_start(ap, cmd); rsrv = redisc_get_server(srv); if(srv==NULL || cmd==NULL || res==NULL) { LM_ERR("invalid parameters"); goto error_exec; } if(srv->len==0 || res->len==0 || cmd->len==0) { LM_ERR("invalid parameters"); goto error_exec; } if(rsrv==NULL) { LM_ERR("no redis server found: %.*s\n", srv->len, srv->s); goto error_exec; } if(rsrv->ctxRedis==NULL) { LM_ERR("no redis context for server: %.*s\n", srv->len, srv->s); goto error_exec; } rpl = redisc_get_reply(res); if(rpl==NULL) { LM_ERR("no redis reply id found: %.*s\n", res->len, res->s); goto error_exec; } if(rpl->rplRedis!=NULL) { /* clean up previous redis reply */ freeReplyObject(rpl->rplRedis); rpl->rplRedis = NULL; } c = cmd->s[cmd->len]; cmd->s[cmd->len] = '\0'; rpl->rplRedis = redisvCommand(rsrv->ctxRedis, cmd->s, ap ); if(rpl->rplRedis == NULL) { /* null reply, reconnect and try again */ if(rsrv->ctxRedis->err) { LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr); } if(redisc_reconnect_server(rsrv)==0) { rpl->rplRedis = redisvCommand(rsrv->ctxRedis, cmd->s, ap); } else { LM_ERR("unable to reconnect to redis server: %.*s\n", srv->len, srv->s); cmd->s[cmd->len] = c; goto error_exec; } } cmd->s[cmd->len] = c; va_end(ap); return 0; error_exec: va_end(ap); return -1; }
int redisc_append_cmd(str *srv, str *res, str *cmd, ...) { redisc_server_t *rsrv=NULL; redisc_reply_t *rpl; char c; va_list ap; va_start(ap, cmd); if(srv==NULL || cmd==NULL || res==NULL) { LM_ERR("invalid parameters"); goto error_cmd; } if(srv->len==0 || res->len==0 || cmd->len==0) { LM_ERR("invalid parameters"); goto error_cmd; } rsrv = redisc_get_server(srv); if(rsrv==NULL) { LM_ERR("no redis server found: %.*s\n", srv->len, srv->s); goto error_cmd; } if(rsrv->ctxRedis==NULL) { LM_ERR("no redis context for server: %.*s\n", srv->len, srv->s); goto error_cmd; } if (rsrv->piped.pending_commands >= MAXIMUM_PIPELINED_COMMANDS) { LM_ERR("Too many pipelined commands, maximum is %d\n",MAXIMUM_PIPELINED_COMMANDS); goto error_cmd; } rpl = redisc_get_reply(res); if(rpl==NULL) { LM_ERR("no redis reply id found: %.*s\n", res->len, res->s); goto error_cmd; } c = cmd->s[cmd->len]; cmd->s[cmd->len] = '\0'; rsrv->piped.commands[rsrv->piped.pending_commands].len = redisvFormatCommand( &rsrv->piped.commands[rsrv->piped.pending_commands].s, cmd->s, ap); if (rsrv->piped.commands[rsrv->piped.pending_commands].len < 0) { LM_ERR("Invalid redis command : %s\n",cmd->s); goto error_cmd; } rsrv->piped.replies[rsrv->piped.pending_commands]=rpl; rsrv->piped.pending_commands++; cmd->s[cmd->len] = c; va_end(ap); return 0; error_cmd: va_end(ap); return -1; }