/* =============================================================================== mjredis_cmd_generic run redis cmd =============================================================================== */ static redisReply* mjredis_cmd_generic(mjredis handle, int* retval, const char* format, ...) { // link is invalid try connect if (!handle->_context && !mjredis_connect(handle)) { *retval = -2; return NULL; } // run command int retry = 1; va_list ap; redisReply* reply = NULL; for (;;) { // call redis command va_start(ap, format); reply = redisvCommand(handle->_context, format, ap); va_end(ap); // no link error break if (reply) break; if (!retry) { MJLOG_ERR("max retry reached"); *retval = -2; return NULL; } // re connect if (!mjredis_connect(handle)) { MJLOG_ERR("reconnect failed"); *retval = -2; return NULL; } retry--; } // MJLOG_ERR("type: %d, integer: %lld, str: %s", reply->type, reply->integer, reply->str); // check reply error if (reply->type == REDIS_REPLY_ERROR) { freeReplyObject(reply); *retval = -1; return NULL; } *retval = 0; return reply; }
EpochlibRedisExecute RedisConnector::execute(const char *format, ...) { this->_reconnect(0); va_list ap; EpochlibRedisExecute returnObj; redisReply *reply = NULL; while (reply == NULL) { // Lock, execute, unlock this->contextMutex.lock(); va_start(ap, format); reply = (redisReply *)redisvCommand(this->context, format, ap); va_end(ap); this->contextMutex.unlock(); if (reply->type == REDIS_REPLY_ERROR) { returnObj.success = false; returnObj.message = reply->str; this->config.logger->log("[Redis] Error command " + std::string(reply->str)); } else { returnObj.success = true; if (reply->type == REDIS_REPLY_STRING) { returnObj.message = reply->str; } else if (reply->type == REDIS_REPLY_INTEGER) { std::stringstream IntToString; IntToString << reply->integer; returnObj.message = IntToString.str(); } } } freeReplyObject(reply); return returnObj; }
/* * execute Redis command and deal with return value */ static redisReply* oidc_cache_redis_command(request_rec *r, oidc_cache_cfg_redis_t *context, const char *format, ...) { redisContext *ctx = NULL; redisReply *reply = NULL; int i = 0; /* try to execute a command at max 2 times while reconnecting */ for (i = 0; i < 2; i++) { /* connect */ ctx = oidc_cache_redis_connect(r, context); if (ctx == NULL) break; /* execute the command */ va_list args; va_start(args, format); reply = redisvCommand(ctx, format, args); va_end(args); /* errors will result in an empty reply */ if (reply != NULL) break; /* something went wrong, log it */ oidc_error(r, "redisvCommand (%d) failed, disconnecting: '%s'", i, ctx->errstr); /* cleanup, we may try again (once) after reconnecting */ redisFree(ctx); apr_pool_userdata_set(NULL, OIDC_CACHE_REDIS_CONTEXT, apr_pool_cleanup_null, r->server->process->pool); } return reply; }
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; }
bool CRedisClient::command(INT64 &iRetType,INT64 &iRetVal,CString &sRetData,CStringArray &listval,const char *cmd, ...) { bool bRet = false; va_list args; va_start(args, cmd); redisReply *reply = static_cast<redisReply*>(redisvCommand(m_Ctx, cmd, args)); va_end(args); if (CheckReply(reply)) { iRetType = reply->type; bRet = true; switch(reply->type) { case REDIS_REPLY_STRING: { sRetData = reply->str; } break; case REDIS_REPLY_ARRAY: { getscanlist(reply,listval); return true; } break; case REDIS_REPLY_INTEGER: { iRetVal = reply->integer; } break; case REDIS_REPLY_NIL: { bRet = false; } break; case REDIS_REPLY_STATUS: { bRet = (_stricmp(reply->str,"OK") == 0)?true:false; } break; case REDIS_REPLY_ERROR: { bRet = false; } break; default: { bRet = false; } } } if(!bRet) { if (reply != NULL) { m_ErrorMessage = reply->str; } bRet = false; } if (reply != NULL) { freeReplyObject(reply); } return bRet; }
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; }