int redisAppendCommand(redisContext *c, const char *format, ...) { va_list ap; int ret; va_start(ap,format); ret = redisvAppendCommand(c,format,ap); va_end(ap); return ret; }
void RedisCon::append(const char* format, ...) { va_list ap; va_start(ap, format); int ret = redisvAppendCommand(connect_.get(), format, ap); va_end(ap); if (ret != REDIS_OK) { throw redis_transport_except(connect_->errstr); } }
int rs_redis_append_command(rs_slave_info_t *si, const char *fmt, ...) { va_list args; redisContext *c; int i, err; i = 0; err = 0; c = si->c; for( ;; ) { if(c == NULL) { /* retry connect*/ c = redisConnect(si->redis_addr, si->redis_port); if(c->err) { if(i % 60 == 0) { i = 0; rs_log_error(RS_LOG_ERR, rs_errno, "redisConnect(\"%s\", " "%d) failed, %s" , si->redis_addr, si->redis_port, c->errstr); } redisFree(c); c = NULL; i += RS_REDIS_CONNECT_RETRY_SLEEP_SEC; sleep(RS_REDIS_CONNECT_RETRY_SLEEP_SEC); continue; } } va_start(args, fmt); err = redisvAppendCommand(c, fmt, args); va_end(args); break; } si->c = c; if(err != REDIS_OK) { rs_log_error(RS_LOG_ERR, rs_errno, "redisvAppendCommand() failed"); return RS_ERR; } si->cmdn++; return RS_OK; }
//------------------------------------------------------------------------------------- bool DBInterfaceRedis::queryAppend(bool printlog, const char* format, ...) { va_list ap; va_start(ap, format); KBE_ASSERT(pRedisContext_); int ret = redisvAppendCommand(pRedisContext_, format, ap); if(lastquery_.size() > 0 && lastquery_[lastquery_.size() - 1] != ';') lastquery_ = ""; char buffer[1024]; int cnt = vsnprintf(buffer, sizeof(buffer) - 1, format, ap); if(cnt > 0) { lastquery_ += buffer; lastquery_ += ";"; RedisWatcher::querystatistics(buffer, cnt); } if (ret == REDIS_ERR) { if(printlog) { ERROR_MSG(fmt::format("DBInterfaceRedis::queryAppend: cmd={}, errno={}, error={}\n", lastquery_, pRedisContext_->err, pRedisContext_->errstr)); } va_end(ap); this->throwError(NULL); return false; } if(printlog) { INFO_MSG("DBInterfaceRedis::queryAppend: successfully!\n"); } va_end(ap); return true; }
void *redisvCommand(redisContext *c, const char *format, va_list ap) { if (redisvAppendCommand(c,format,ap) != REDIS_OK) return NULL; return __redisBlockForReply(c); }
void redisAppendCommand(redisContext *c, const char *format, ...) { va_list ap; va_start(ap,format); redisvAppendCommand(c,format,ap); va_end(ap); }
/** Execute a script against Redis cluster * * Handles uploading the script to the server if required. * * @note All replies will be freed on error. * * @param[out] out Where to write Redis reply object resulting from the command. * @param[in] request The current request. * @param[in] cluster configuration. * @param[in] key to use to determine the cluster node. * @param[in] key_len length of the key. * @param[in] wait_num If > 0 wait until this many slaves have replicated the data * from the last command. * @param[in] wait_timeout How long to wait for slaves. * @param[in] digest of script. * @param[in] script to upload. * @param[in] cmd EVALSHA command to execute. * @param[in] ... Arguments for the eval command. * @return status of the command. */ static fr_redis_rcode_t ippool_script(redisReply **out, REQUEST *request, fr_redis_cluster_t *cluster, uint8_t const *key, size_t key_len, uint32_t wait_num, uint32_t wait_timeout, char const digest[], char const *script, char const *cmd, ...) { fr_redis_conn_t *conn; redisReply *replies[5]; /* Must be equal to the maximum number of pipelined commands */ size_t reply_cnt = 0, i; fr_redis_cluster_state_t state; fr_redis_rcode_t s_ret, status; unsigned int pipelined = 0; va_list ap; *out = NULL; #ifndef NDEBUG memset(replies, 0, sizeof(replies)); #endif va_start(ap, cmd); for (s_ret = fr_redis_cluster_state_init(&state, &conn, cluster, request, key, key_len, false); s_ret == REDIS_RCODE_TRY_AGAIN; /* Continue */ s_ret = fr_redis_cluster_state_next(&state, &conn, cluster, request, status, &replies[0])) { va_list copy; RDEBUG3("Calling script 0x%s", digest); va_copy(copy, ap); /* copy or segv */ redisvAppendCommand(conn->handle, cmd, copy); va_end(copy); pipelined = 1; if (wait_num) { redisAppendCommand(conn->handle, "WAIT %i %i", wait_num, wait_timeout); pipelined++; } reply_cnt = fr_redis_pipeline_result(&pipelined, &status, replies, sizeof(replies) / sizeof(*replies), conn); if (status != REDIS_RCODE_NO_SCRIPT) continue; /* * Clear out the existing reply */ fr_redis_pipeline_free(replies, reply_cnt); /* * Last command failed with NOSCRIPT, this means * we have to send the Lua script up to the node * so it can be cached. */ RDEBUG3("Loading script 0x%s", digest); redisAppendCommand(conn->handle, "MULTI"); redisAppendCommand(conn->handle, "SCRIPT LOAD %s", script); va_copy(copy, ap); /* copy or segv */ redisvAppendCommand(conn->handle, cmd, copy); va_end(copy); redisAppendCommand(conn->handle, "EXEC"); pipelined = 4; if (wait_num) { redisAppendCommand(conn->handle, "WAIT %i %i", wait_num, wait_timeout); pipelined++; } reply_cnt = fr_redis_pipeline_result(&pipelined, &status, replies, sizeof(replies) / sizeof(*replies), conn); if (status == REDIS_RCODE_SUCCESS) { if (RDEBUG_ENABLED3) for (i = 0; i < reply_cnt; i++) { fr_redis_reply_print(L_DBG_LVL_3, replies[i], request, i); } if (replies[3]->type != REDIS_REPLY_ARRAY) { REDEBUG("Bad response to EXEC, expected array got %s", fr_int2str(redis_reply_types, replies[3]->type, "<UNKNOWN>")); error: fr_redis_pipeline_free(replies, reply_cnt); status = REDIS_RCODE_ERROR; goto finish; } if (replies[3]->elements != 2) { REDEBUG("Bad response to EXEC, expected 2 result elements, got %zu", replies[3]->elements); goto error; } if (replies[3]->element[0]->type != REDIS_REPLY_STRING) { REDEBUG("Bad response to SCRIPT LOAD, expected string got %s", fr_int2str(redis_reply_types, replies[3]->element[0]->type, "<UNKNOWN>")); goto error; } if (strcmp(replies[3]->element[0]->str, digest) != 0) { RWDEBUG("Incorrect SHA1 from SCRIPT LOAD, expected %s, got %s", digest, replies[3]->element[0]->str); goto error; } } } if (s_ret != REDIS_RCODE_SUCCESS) goto error; switch (reply_cnt) { case 2: /* EVALSHA with wait */ if (ippool_wait_check(request, wait_num, replies[1]) < 0) goto error; fr_redis_reply_free(&replies[1]); /* Free the wait response */ break; case 1: /* EVALSHA */ *out = replies[0]; break; case 5: /* LOADSCRIPT + EVALSHA + WAIT */ if (ippool_wait_check(request, wait_num, replies[4]) < 0) goto error; fr_redis_reply_free(&replies[4]); /* Free the wait response */ /* FALL-THROUGH */ case 4: /* LOADSCRIPT + EVALSHA */ fr_redis_reply_free(&replies[2]); /* Free the queued cmd response*/ fr_redis_reply_free(&replies[1]); /* Free the queued script load response */ fr_redis_reply_free(&replies[0]); /* Free the queued multi response */ *out = replies[3]->element[1]; replies[3]->element[1] = NULL; /* Prevent double free */ fr_redis_reply_free(&replies[3]); /* This works because hiredis checks for NULL elements */ break; case 0: break; } finish: va_end(ap); return s_ret; }