/** * Executes a redis command. * Command is coded using a vector of strings, and a vector of lenghts. * * @param rsrv Pointer to a redis_server_t structure. * @param argc number of elements in the command vector. * @param argv vector of zero terminated strings forming the command. * @param argvlen vector of command string lenghts or NULL. * @return redisReply structure or NULL if there was an error. */ void * redisc_exec_argv(redisc_server_t *rsrv, int argc, const char **argv, const size_t *argvlen) { redisReply *res=NULL; if(rsrv==NULL || rsrv->ctxRedis==NULL) { LM_ERR("no redis context found for server %.*s\n", rsrv->sname->len, rsrv->sname->s); return NULL; } if(argc<=0) { LM_ERR("invalid parameters\n"); return NULL; } if(argv==NULL || *argv==NULL) { LM_ERR("invalid parameters\n"); return NULL; } res = redisCommandArgv(rsrv->ctxRedis, argc, argv, argvlen); if(res) { return res; } /* 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) { res = redisCommandArgv(rsrv->ctxRedis, argc, argv, argvlen); } else { LM_ERR("Unable to reconnect to server: %.*s\n", rsrv->sname->len, rsrv->sname->s); return NULL; } return res; }
int redisc_create_pipelined_message(redisc_server_t *rsrv) { int i; if (rsrv->ctxRedis->err) { LM_DBG("Reconnecting server because of error %d: \"%s\"",rsrv->ctxRedis->err,rsrv->ctxRedis->errstr); if (redisc_reconnect_server(rsrv)) { LM_ERR("unable to reconnect to REDIS server: %.*s\n", rsrv->sname->len,rsrv->sname->s); return -1; } } for (i=0;i<rsrv->piped.pending_commands;i++) { if (redis_append_formatted_command(rsrv->ctxRedis,rsrv->piped.commands[i].s,rsrv->piped.commands[i].len) != REDIS_OK) { LM_ERR("Error while appending command %d",i); return -1; } } return 0; }
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; }
/** * Executes a redis command. * Command is coded using a vector of strings, and a vector of lenghts. * * @param rsrv Pointer to a redis_server_t structure. * @param argc number of elements in the command vector. * @param argv vector of zero terminated strings forming the command. * @param argvlen vector of command string lenghts or NULL. * @return redisReply structure or NULL if there was an error. */ redisReply* redisc_exec_argv(redisc_server_t *rsrv, int argc, const char **argv, const size_t *argvlen) { redisReply *res=NULL; if(rsrv==NULL) { LM_ERR("no redis context found for server %.*s\n", (rsrv)?rsrv->sname->len:0, (rsrv)?rsrv->sname->s:""); return NULL; } LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); if(rsrv->ctxRedis==NULL) { LM_ERR("no redis context found for server %.*s\n", (rsrv)?rsrv->sname->len:0, (rsrv)?rsrv->sname->s:""); return NULL; } if(argc<=0) { LM_ERR("invalid parameters\n"); return NULL; } if(argv==NULL || *argv==NULL) { LM_ERR("invalid parameters\n"); return NULL; } again: res = redisCommandArgv(rsrv->ctxRedis, argc, argv, argvlen); /* null reply, reconnect and try again */ if(rsrv->ctxRedis->err) { LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr); } if(res) { if (check_cluster_reply(res, &rsrv)) { goto again; } return res; } if(redisc_reconnect_server(rsrv)==0) { res = redisCommandArgv(rsrv->ctxRedis, argc, argv, argvlen); if (res) { if (check_cluster_reply(res, &rsrv)) { goto again; } } } else { LM_ERR("Unable to reconnect to server: %.*s\n", rsrv->sname->len, rsrv->sname->s); return NULL; } return 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; }