redis-cli: Sleep for a while in each cliConnect when we got connect error in cluster mode. (#8884)

There's an infinite loop when redis-cli fails to connect in cluster mode.
This commit adds a 1 second sleep to prevent flooding the console with errors.
It also adds a specific error print in a few places that could have error without printing anything.

Co-authored-by: Oran Agra <oran@redislabs.com>
(cherry picked from commit 8351a10b959364cff9fc026188ebc9c653ef230a)
This commit is contained in:
Binbin 2021-05-18 15:09:45 +08:00 committed by Oran Agra
parent 1ce06604de
commit 9da232c05a

View File

@ -793,13 +793,19 @@ static int cliAuth(redisContext *ctx, char *user, char *auth) {
reply = redisCommand(ctx,"AUTH %s",auth);
else
reply = redisCommand(ctx,"AUTH %s %s",user,auth);
if (reply != NULL) {
if (reply->type == REDIS_REPLY_ERROR)
fprintf(stderr,"Warning: AUTH failed\n");
freeReplyObject(reply);
return REDIS_OK;
if (reply == NULL) {
fprintf(stderr, "\nI/O error\n");
return REDIS_ERR;
}
return REDIS_ERR;
int result = REDIS_OK;
if (reply->type == REDIS_REPLY_ERROR) {
result = REDIS_ERR;
fprintf(stderr, "AUTH failed: %s\n", reply->str);
}
freeReplyObject(reply);
return result;
}
/* Send SELECT input_dbnum to the server */
@ -808,19 +814,21 @@ static int cliSelect(void) {
if (config.input_dbnum == config.dbnum) return REDIS_OK;
reply = redisCommand(context,"SELECT %d",config.input_dbnum);
if (reply != NULL) {
int result = REDIS_OK;
if (reply->type == REDIS_REPLY_ERROR) {
result = REDIS_ERR;
fprintf(stderr,"SELECT %d failed: %s\n",config.input_dbnum,reply->str);
} else {
config.dbnum = config.input_dbnum;
cliRefreshPrompt();
}
freeReplyObject(reply);
return result;
if (reply == NULL) {
fprintf(stderr, "\nI/O error\n");
return REDIS_ERR;
}
return REDIS_ERR;
int result = REDIS_OK;
if (reply->type == REDIS_REPLY_ERROR) {
result = REDIS_ERR;
fprintf(stderr,"SELECT %d failed: %s\n",config.input_dbnum,reply->str);
} else {
config.dbnum = config.input_dbnum;
cliRefreshPrompt();
}
freeReplyObject(reply);
return result;
}
/* Select RESP3 mode if redis-cli was started with the -3 option. */
@ -829,16 +837,18 @@ static int cliSwitchProto(void) {
if (config.resp3 == 0) return REDIS_OK;
reply = redisCommand(context,"HELLO 3");
if (reply != NULL) {
int result = REDIS_OK;
if (reply->type == REDIS_REPLY_ERROR) {
result = REDIS_ERR;
fprintf(stderr,"HELLO 3 failed: %s\n",reply->str);
}
freeReplyObject(reply);
return result;
if (reply == NULL) {
fprintf(stderr, "\nI/O error\n");
return REDIS_ERR;
}
return REDIS_ERR;
int result = REDIS_OK;
if (reply->type == REDIS_REPLY_ERROR) {
result = REDIS_ERR;
fprintf(stderr,"HELLO 3 failed: %s\n",reply->str);
}
freeReplyObject(reply);
return result;
}
/* Connect to the server. It is possible to pass certain flags to the function:
@ -875,12 +885,15 @@ static int cliConnect(int flags) {
if (context->err) {
if (!(flags & CC_QUIET)) {
fprintf(stderr,"Could not connect to Redis at ");
if (config.hostsocket == NULL)
fprintf(stderr,"%s:%d: %s\n",
if (config.hostsocket == NULL ||
(config.cluster_mode && config.cluster_reissue_command))
{
fprintf(stderr, "%s:%d: %s\n",
config.hostip,config.hostport,context->errstr);
else
} else {
fprintf(stderr,"%s: %s\n",
config.hostsocket,context->errstr);
}
}
redisFree(context);
context = NULL;
@ -1472,7 +1485,7 @@ static int cliSendCommand(int argc, char **argv, long repeat) {
}
if (config.cluster_reissue_command){
/* If we need to reissue the command, break to prevent a
further 'repeat' number of dud interations */
further 'repeat' number of dud interactions */
break;
}
if (config.interval) usleep(config.interval);
@ -2019,9 +2032,12 @@ static int issueCommandRepeat(int argc, char **argv, long repeat) {
return REDIS_ERR;
}
}
/* Issue the command again if we got redirected in cluster mode */
if (config.cluster_mode && config.cluster_reissue_command) {
cliConnect(CC_FORCE);
/* If cliConnect fails, sleep for a while and try again. */
if (cliConnect(CC_FORCE) != REDIS_OK)
sleep(1);
} else {
break;
}