实现发送基本同步命令,带实现接受数据 #6
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user