实现发送基本同步命令,带实现接受数据

This commit is contained in:
LingZhaoHui 2022-06-08 23:37:02 +08:00
parent 41bf7bf648
commit 1c2425d7ea
4 changed files with 71 additions and 16 deletions

View File

@ -1028,6 +1028,20 @@ static int redisNextInBandReplyFromReader(redisContext *c, void **reply) {
return REDIS_OK; return REDIS_OK;
} }
int redisFlush(redisContext *c) {
int wdone = 0;
void *aux = NULL;
/* Try to read pending replies */
if (redisNextInBandReplyFromReader(c,&aux) == REDIS_ERR)
return REDIS_ERR;
/* Write until done */
do {
if (redisBufferWrite(c,&wdone) == REDIS_ERR)
return REDIS_ERR;
} while (!wdone);
return REDIS_OK;
}
int redisGetReply(redisContext *c, void **reply) { int redisGetReply(redisContext *c, void **reply) {
int wdone = 0; int wdone = 0;
void *aux = NULL; void *aux = NULL;

View File

@ -315,6 +315,7 @@ redisFD redisFreeKeepFd(redisContext *c);
int redisBufferRead(redisContext *c); int redisBufferRead(redisContext *c);
int redisBufferWrite(redisContext *c, int *done); int redisBufferWrite(redisContext *c, int *done);
int redisFlush(redisContext *c);
/* In a blocking context, this function first checks if there are unconsumed /* In a blocking context, this function first checks if there are unconsumed
* replies to return and returns one if so. Otherwise, it flushes the output * replies to return and returns one if so. Otherwise, it flushes the output
* buffer to the socket and reads until it has a reply. In a non-blocking * buffer to the socket and reads until it has a reply. In a non-blocking

View File

@ -16,6 +16,7 @@ migrateObj *createMigrateObject(robj *host, int port, int begin_slot, int end_sl
m->begin_slot = begin_slot; m->begin_slot = begin_slot;
m->end_slot = end_slot; m->end_slot = end_slot;
m->repl_stat = REPL_STATE_NONE; m->repl_stat = REPL_STATE_NONE;
m->isCache = 0;
return m; return m;
} }
@ -25,44 +26,82 @@ void freeMigrateObj(migrateObj *m) {
mobj = NULL; mobj = NULL;
} }
int sendReplCommand(RedisModuleCtx *ctx, char *format, ...) { int sendSyncCommand(RedisModuleCtx *ctx) {
va_list ap;
va_start(ap, format); if (!mobj->isCache) {
redisReply *reply = redisvCommand(mobj->source_cc, format, ap); mobj->isCache = 1;
va_end(ap); mobj->psync_replid = "?";
if (reply == NULL || reply->type == REDIS_REPLY_ERROR) { memcpy(mobj->psync_offset, "-1", 3);
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_WARNING, "send %s failed ip:%s,port:%d, error:%s", }
format, mobj->host, mobj->port, reply->str); if (redisAppendCommand(mobj->source_cc, "PSYNC %s %s", mobj->psync_replid, mobj->psync_offset) != REDIS_OK) {
freeReplyObject(reply); RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_WARNING,
"append PSYNC %s %s failed ip:%s,port:%d, ",
mobj->psync_replid, mobj->psync_offset, mobj->host, mobj->port);
return 0; return 0;
} }
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "%s %s", format, reply->str); if (redisFlush(mobj->source_cc) != REDIS_OK) {
freeReplyObject(reply); RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_WARNING,
"send PSYNC %s %s failed ip:%s,port:%d, ",
mobj->psync_replid, mobj->psync_offset, mobj->host, mobj->port);
return 0;
}
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "PSYNC %s %s ",
mobj->psync_replid, mobj->psync_offset);
return 1; return 1;
} }
void *syncWithRedis(void *arg) { void *syncWithRedis(void *arg) {
RedisModuleCtx *ctx = arg; RedisModuleCtx *ctx = arg;
redisReply *reply;
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "begin sync data"); RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "begin sync data");
if (!sendReplCommand(ctx, "PING")) { reply = redisCommand(mobj->source_cc, "PING");
if (reply->type == REDIS_REPLY_ERROR) {
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_WARNING, "send PING failed ip:%s,port:%d, error:%s",
mobj->host, mobj->port, reply->str);
goto error; goto error;
} }
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "PING ");
freeReplyObject(reply);
//todo auth with master //todo auth with master
sds portstr = sdsfromlonglong(mobj->port); sds portstr = sdsfromlonglong(mobj->port);
if (!sendReplCommand(ctx, "REPLCONF listening-port %s", portstr)) { reply = redisCommand(mobj->source_cc, "REPLCONF listening-port %s", portstr);
if (reply->type == REDIS_REPLY_ERROR) {
sdsfree(portstr); sdsfree(portstr);
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_WARNING, "REPLCONF listening-port %s failed ip:%s,port:%d, error:%s",
portstr, mobj->host, mobj->port, reply->str);
goto error; goto error;
} }
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "REPLCONF listening-port %s ", portstr);
sdsfree(portstr); sdsfree(portstr);
if (!sendReplCommand(ctx, "REPLCONF ip-address %s", mobj->host)) { freeReplyObject(reply);
reply = redisCommand(mobj->source_cc, "REPLCONF ip-address %s", mobj->host);
if (reply->type == REDIS_REPLY_ERROR) {
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_WARNING, "REPLCONF ip-address %s failed ip:%s,port:%d, error:%s",
mobj->host, mobj->host, mobj->port, reply->str);
goto error; goto error;
} }
if (!sendReplCommand(ctx, "REPLCONF %s %s %s %s", "capa", "eof", "capa", "psync2")) { RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "REPLCONF ip-address %s ", mobj->host);
freeReplyObject(reply);
reply = redisCommand(mobj->source_cc, "REPLCONF %s %s %s %s", "capa", "eof", "capa", "psync2");
if (reply->type == REDIS_REPLY_ERROR) {
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_WARNING,
"REPLCONF capa eof capa psync2 failed ip:%s,port:%d, error:%s",
mobj->host, mobj->port, reply->str);
goto error;
}
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_NOTICE, "REPLCONF %s %s %s %s",
"capa", "eof", "capa", "psync2");
freeReplyObject(reply);
if (!sendSyncCommand(ctx)) {
RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_WARNING,
"send PSYNC %s %s failed ip:%s,port:%d, ",
mobj->psync_replid, mobj->psync_offset, mobj->host, mobj->port);
goto error; goto error;
} }
return NULL; return NULL;
error: error:
freeReplyObject(reply);
freeMigrateObj(mobj); freeMigrateObj(mobj);
return NULL; return NULL;
} }

View File

@ -35,6 +35,7 @@ typedef struct migrateObject {
int begin_slot; int begin_slot;
int end_slot; int end_slot;
char *psync_replid; char *psync_replid;
int isCache;
char psync_offset[32]; char psync_offset[32];
} migrateObj; } migrateObj;
@ -64,7 +65,7 @@ migrateObj *createMigrateObject(robj *host, int port, int begin_slot, int end_sl
void freeMigrateObj(migrateObj *m); void freeMigrateObj(migrateObj *m);
int sendReplCommand(RedisModuleCtx *ctx, char *format, ...); int sendSyncCommand(RedisModuleCtx *ctx);
void *syncWithRedis(void *arg); void *syncWithRedis(void *arg);