Skip to content

Commit

Permalink
More Sentinel fixes (inc. a memleak)
Browse files Browse the repository at this point in the history
  • Loading branch information
attipaci committed Jan 12, 2025
1 parent 5b774f3 commit 0e8c2a9
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 41 deletions.
1 change: 1 addition & 0 deletions include/redisx-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ typedef struct {
// in redisx.c ---------------------------->
int rCopyConfig(const RedisConfig *src, Redis *dst);
void rClearConfig(RedisConfig *config);
XLookupTable *rConsumeInfoReply(RESP *reply);

// in redisx-sub.c ------------------------>
int rConfigLock(Redis *redis);
Expand Down
1 change: 0 additions & 1 deletion include/redisx.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,6 @@ int redisxUnlockClient(RedisClient *cl);
int redisxSendRequestAsync(RedisClient *cl, const char *command, const char *arg1, const char *arg2, const char *arg3);
int redisxSendArrayRequestAsync(RedisClient *cl, const char **args, const int *length, int n);
int redisxClusterAskMigratingAsync(RedisClient *cl, const char **args, const int *lengths, int n);
XLookupTable *redisxGetInfoAsync(RedisClient *cl, const char *parameter);
int redisxSetValueAsync(RedisClient *cl, const char *table, const char *key, const char *value, boolean confirm);
int redisxMultiSetAsync(RedisClient *cl, const char *table, const RedisEntry *entries, int n, boolean confirm);
int redisxGetAvailableAsync(RedisClient *cl);
Expand Down
12 changes: 10 additions & 2 deletions src/redisx-sentinel.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,18 @@ int rConfirmMasterRoleAsync(Redis *redis) {
prop_error(fn, status);

if(redisxCheckDestroyRESP(reply, RESP_ARRAY, 0) != X_SUCCESS) {
// Fallback to using INFO replication...
XLookupTable *info = redisxGetInfoAsync(redis->interactive, "replication");
XLookupTable *info;
RESP *reply;
const XField *role;

// Fallback to using INFO replication...
status = redisxSendRequestAsync(redis->interactive, "INFO", "replication", NULL, NULL);
prop_error(fn, status);

reply = redisxReadReplyAsync(redis->interactive, &status);
prop_error(fn, status);

info = rConsumeInfoReply(reply);
if(!info) return x_trace(fn, NULL, X_FAILURE);

role = xLookupField(info, "role");
Expand Down
43 changes: 5 additions & 38 deletions src/redisx.c
Original file line number Diff line number Diff line change
Expand Up @@ -865,14 +865,14 @@ RESP *redisxGetHelloData(Redis *redis) {
* @param reply The response to an `INFO` query
* @return An allocated lookup table containing the key/value pairs extracted
*/
static XLookupTable *rProcessInfoReply(const RESP *reply) {
XLookupTable *rConsumeInfoReply(RESP *reply) {
static const char *fn = "rProcessInfoReply";

XStructure *s;
XLookupTable *lookup;
const char *line;

if(redisxCheckRESP(reply, RESP_BULK_STRING, 0) != 0) return x_trace_null(fn, NULL);
if(redisxCheckDestroyRESP(reply, RESP_BULK_STRING, 0) != 0) return x_trace_null(fn, NULL);

s = xCreateStruct();

Expand All @@ -884,11 +884,12 @@ static XLookupTable *rProcessInfoReply(const RESP *reply) {
char *sep = strchr(line, ':');
if(sep) {
*sep = '\0';
xSetField(s, xCreateStringField(line, xStringCopyOf(sep + 1)));
xSetField(s, xCreateStringField(line, sep + 1));
}
line = strtok(NULL, "\n");
}

redisxDestroyRESP(reply);

lookup = xCreateLookup(s, FALSE);
free(s);
Expand Down Expand Up @@ -919,41 +920,7 @@ XLookupTable *redisxGetInfo(Redis *redis, const char *parameter) {
reply = redisxRequest(redis, "INFO", parameter, NULL, NULL, &status);
if(status) return x_trace_null(fn, NULL);

lookup = rProcessInfoReply(reply);
if(!lookup) return x_trace_null(fn, NULL);

redisxDestroyRESP(reply);

return lookup;
}

/**
* Returns the result of an INFO query (with the optional parameter) as a lookup table
* of keywords and string values. The caller should have exclusive access to the given
* client.
*
* @param cl A locked and connected Redis client instance.
* @param parameter Optional parameter to pass with INFO, or NULL.
* @return a newly created lookup table with the string key/value pairs of the
* response from the Redis server, or NULL if there was an error.
* The caller should destroy the lookup table after using it.
*
* @sa redisxGetInfo()
*/
XLookupTable *redisxGetInfoAsync(RedisClient *cl, const char *parameter) {
static const char *fn = "redisxGetInfo";

RESP *reply;
XLookupTable *lookup;
int status;

status = redisxSendRequestAsync(cl, "INFO", parameter, NULL, NULL);
if(status) return x_trace_null(fn, NULL);

reply = redisxReadReplyAsync(cl, &status);
if(status) return x_trace_null(fn, NULL);

lookup = rProcessInfoReply(reply);
lookup = rConsumeInfoReply(reply);
if(!lookup) return x_trace_null(fn, NULL);

redisxDestroyRESP(reply);
Expand Down

0 comments on commit 0e8c2a9

Please sign in to comment.