add sync code
This commit is contained in:
parent
dbe28cd4ff
commit
b55cf2bc7e
|
@ -13,4 +13,8 @@ target_include_directories(
|
|||
sync
|
||||
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/sync"
|
||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||
)
|
||||
)
|
||||
|
||||
if(${BUILD_TEST})
|
||||
add_subdirectory(test)
|
||||
endif(${BUILD_TEST})
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncInt.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaft.h"
|
||||
#include "taosdef.h"
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncInt.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaft.h"
|
||||
#include "taosdef.h"
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncInt.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_LIBS_SYNC_ENV_H
|
||||
#define _TD_LIBS_SYNC_ENV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncInt.h"
|
||||
#include "taosdef.h"
|
||||
#include "trpc.h"
|
||||
|
||||
typedef struct SSyncEnv {
|
||||
void *pTimer;
|
||||
void *pTimerManager;
|
||||
} SSyncEnv;
|
||||
|
||||
int32_t syncEnvStart();
|
||||
|
||||
int32_t syncEnvStop();
|
||||
|
||||
static int32_t doSyncEnvStart(SSyncEnv *pSyncEnv);
|
||||
|
||||
static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_LIBS_SYNC_ENV_H*/
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_LIBS_IO_H
|
||||
#define _TD_LIBS_IO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "os.h"
|
||||
#include "syncInt.h"
|
||||
#include "taosdef.h"
|
||||
#include "tqueue.h"
|
||||
#include "trpc.h"
|
||||
|
||||
typedef struct SSyncIO {
|
||||
void * serverRpc;
|
||||
void * clientRpc;
|
||||
STaosQueue *pMsgQ;
|
||||
STaosQset * pQset;
|
||||
pthread_t tid;
|
||||
int8_t isStart;
|
||||
|
||||
SEpSet epSet;
|
||||
|
||||
void *syncTimer;
|
||||
void *syncTimerManager;
|
||||
|
||||
int32_t (*start)(struct SSyncIO *ths);
|
||||
int32_t (*stop)(struct SSyncIO *ths);
|
||||
int32_t (*ping)(struct SSyncIO *ths);
|
||||
int32_t (*onMessage)(struct SSyncIO *ths, void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||
int32_t (*destroy)(struct SSyncIO *ths);
|
||||
|
||||
} SSyncIO;
|
||||
|
||||
int32_t syncIOStart();
|
||||
int32_t syncIOStop();
|
||||
|
||||
SSyncIO *syncIOCreate();
|
||||
|
||||
static int32_t doSyncIOStart(SSyncIO *io);
|
||||
static int32_t doSyncIOStop(SSyncIO *io);
|
||||
static int32_t doSyncIOPing(SSyncIO *io);
|
||||
static int32_t doSyncIOOnMessage(struct SSyncIO *io, void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||
static int32_t doSyncIODestroy(SSyncIO *io);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_LIBS_IO_H*/
|
|
@ -23,8 +23,11 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncMessage.h"
|
||||
#include "sync.h"
|
||||
#include "taosdef.h"
|
||||
#include "tlog.h"
|
||||
|
||||
extern int32_t sDebugFlag;
|
||||
|
||||
#define sFatal(...) \
|
||||
{ \
|
||||
|
@ -64,6 +67,25 @@ extern "C" {
|
|||
}
|
||||
|
||||
struct SRaft;
|
||||
typedef struct SRaft SRaft;
|
||||
|
||||
struct SyncPing;
|
||||
typedef struct SyncPing SyncPing;
|
||||
|
||||
struct SyncPingReply;
|
||||
typedef struct SyncPingReply SyncPingReply;
|
||||
|
||||
struct SyncRequestVote;
|
||||
typedef struct SyncRequestVote SyncRequestVote;
|
||||
|
||||
struct SyncRequestVoteReply;
|
||||
typedef struct SyncRequestVoteReply SyncRequestVoteReply;
|
||||
|
||||
struct SyncAppendEntries;
|
||||
typedef struct SyncAppendEntries SyncAppendEntries;
|
||||
|
||||
struct SyncAppendEntriesReply;
|
||||
typedef struct SyncAppendEntriesReply SyncAppendEntriesReply;
|
||||
|
||||
typedef struct SSyncNode {
|
||||
int8_t replica;
|
||||
|
@ -73,7 +95,7 @@ typedef struct SSyncNode {
|
|||
SSyncCfg syncCfg;
|
||||
char path[TSDB_FILENAME_LEN];
|
||||
|
||||
struct SRaft* pRaft;
|
||||
SRaft* pRaft;
|
||||
|
||||
int32_t (*FpPing)(struct SSyncNode* ths, const SyncPing* pMsg);
|
||||
|
||||
|
@ -117,6 +139,8 @@ static int32_t onSyncNodeAppendEntries(struct SSyncNode* ths, SyncAppendEntries*
|
|||
|
||||
static int32_t onSyncNodeAppendEntriesReply(struct SSyncNode* ths, SyncAppendEntriesReply* pMsg);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
|||
#include "taosdef.h"
|
||||
|
||||
typedef struct SRaftId {
|
||||
SyncNodeId nodeId;
|
||||
SyncNodeId addr;
|
||||
SyncGroupId vgId;
|
||||
} SRaftId;
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_LIBS_TPL_H
|
||||
#define _TD_LIBS_TPL_H
|
||||
#ifndef _TD_LIBS_SYNC_RAFT_ENTRY_H
|
||||
#define _TD_LIBS_SYNC_RAFT_ENTRY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "sync.h"
|
||||
#include "syncInt.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
typedef struct SSyncRaftEntry {
|
||||
|
@ -37,4 +37,4 @@ typedef struct SSyncRaftEntry {
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_LIBS_TPL_H*/
|
||||
#endif /*_TD_LIBS_SYNC_RAFT_ENTRY_H*/
|
||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "sync.h"
|
||||
#include "syncInt.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncBuffer* pBuf);
|
||||
|
|
|
@ -23,17 +23,37 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "sync.h"
|
||||
#include "cJSON.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaft.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
int32_t currentTerm(SyncTerm *pCurrentTerm);
|
||||
#define RAFT_STORE_BLOCK_SIZE 512
|
||||
#define RAFT_STORE_PATH_LEN 128
|
||||
|
||||
int32_t persistCurrentTerm(SyncTerm currentTerm);
|
||||
typedef struct SRaftStore {
|
||||
SyncTerm currentTerm;
|
||||
SRaftId voteFor;
|
||||
FileFd fd;
|
||||
char path[RAFT_STORE_PATH_LEN];
|
||||
} SRaftStore;
|
||||
|
||||
int32_t voteFor(SRaftId *pRaftId);
|
||||
SRaftStore *raftStoreOpen(const char *path);
|
||||
|
||||
static int32_t raftStoreInit(SRaftStore *pRaftStore);
|
||||
|
||||
int32_t raftStoreClose(SRaftStore *pRaftStore);
|
||||
|
||||
int32_t raftStorePersist(SRaftStore *pRaftStore);
|
||||
|
||||
static bool raftStoreFileExist(char *path);
|
||||
|
||||
int32_t raftStoreSerialize(SRaftStore *pRaftStore, char *buf, size_t len);
|
||||
|
||||
int32_t raftStoreDeserialize(SRaftStore *pRaftStore, char *buf, size_t len);
|
||||
|
||||
void raftStorePrint(SRaftStore *pRaftStore);
|
||||
|
||||
int32_t persistVoteFor(SRaftId *pRaftId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncInt.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncInt.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaft.h"
|
||||
#include "taosdef.h"
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncInt.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaft.h"
|
||||
#include "taosdef.h"
|
||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "sync.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaft.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncInt.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaft.h"
|
||||
#include "taosdef.h"
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_LIBS_SYNC_VOTG_MGR_H
|
||||
#define _TD_LIBS_SYNC_VOTG_MGR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncInt.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_LIBS_SYNC_VOTG_MGR_H*/
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "syncAppendEntries.h"
|
||||
#include "sync.h"
|
||||
|
||||
void appendEntries(SRaft *pRaft, const SyncAppendEntries *pMsg) {
|
||||
// TLA+ Spec
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "syncAppendEntriesReply.h"
|
||||
#include "sync.h"
|
||||
|
||||
void onAppendEntriesReply(SRaft *pRaft, const SyncAppendEntriesReply *pMsg) {
|
||||
// TLA+ Spec
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sync.h"
|
||||
#include "syncElection.h"
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "syncEnv.h"
|
||||
#include <assert.h>
|
||||
|
||||
SSyncEnv *gSyncEnv = NULL;
|
||||
|
||||
int32_t syncEnvStart() {
|
||||
int32_t ret;
|
||||
gSyncEnv = (SSyncEnv *)malloc(sizeof(SSyncEnv));
|
||||
assert(gSyncEnv != NULL);
|
||||
ret = doSyncEnvStart(gSyncEnv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncEnvStop() {
|
||||
int32_t ret = doSyncEnvStop(gSyncEnv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t doSyncEnvStart(SSyncEnv *pSyncEnv) { return 0; }
|
||||
|
||||
static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv) { return 0; }
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "syncIO.h"
|
||||
#include <tep.h>
|
||||
#include "syncOnMessage.h"
|
||||
#include "tglobal.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
||||
int32_t syncIOStart() { return 0; }
|
||||
|
||||
int32_t syncIOStop() { return 0; }
|
||||
|
||||
static void syncTick(void *param, void *tmrId) {
|
||||
SSyncIO *io = (SSyncIO *)param;
|
||||
sDebug("syncTick ... ");
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
rpcMsg.pCont = rpcMallocCont(10);
|
||||
snprintf(rpcMsg.pCont, 10, "TICK");
|
||||
rpcMsg.contLen = 10;
|
||||
rpcMsg.handle = NULL;
|
||||
rpcMsg.msgType = 2;
|
||||
|
||||
SRpcMsg *pTemp;
|
||||
|
||||
pTemp = taosAllocateQitem(sizeof(SRpcMsg));
|
||||
memcpy(pTemp, &rpcMsg, sizeof(SRpcMsg));
|
||||
|
||||
taosWriteQitem(io->pMsgQ, pTemp);
|
||||
|
||||
io->syncTimer = taosTmrStart(syncTick, 1000, io, io->syncTimerManager);
|
||||
}
|
||||
|
||||
void *syncConsumer(void *param) {
|
||||
SSyncIO *io = param;
|
||||
|
||||
STaosQall *qall;
|
||||
SRpcMsg * pRpcMsg, rpcMsg;
|
||||
int type;
|
||||
|
||||
qall = taosAllocateQall();
|
||||
|
||||
while (1) {
|
||||
int numOfMsgs = taosReadAllQitemsFromQset(io->pQset, qall, NULL, NULL);
|
||||
sDebug("%d sync-io msgs are received", numOfMsgs);
|
||||
if (numOfMsgs <= 0) break;
|
||||
|
||||
for (int i = 0; i < numOfMsgs; ++i) {
|
||||
taosGetQitem(qall, (void **)&pRpcMsg);
|
||||
sDebug("sync-io recv type:%d msg:%s", pRpcMsg->msgType, (char *)(pRpcMsg->pCont));
|
||||
}
|
||||
|
||||
taosResetQitems(qall);
|
||||
for (int i = 0; i < numOfMsgs; ++i) {
|
||||
taosGetQitem(qall, (void **)&pRpcMsg);
|
||||
rpcFreeCont(pRpcMsg->pCont);
|
||||
|
||||
if (pRpcMsg->handle != NULL) {
|
||||
int msgSize = 128;
|
||||
memset(&rpcMsg, 0, sizeof(rpcMsg));
|
||||
rpcMsg.pCont = rpcMallocCont(msgSize);
|
||||
rpcMsg.contLen = msgSize;
|
||||
rpcMsg.handle = pRpcMsg->handle;
|
||||
rpcMsg.code = 0;
|
||||
rpcSendResponse(&rpcMsg);
|
||||
}
|
||||
|
||||
taosFreeQitem(pRpcMsg);
|
||||
}
|
||||
}
|
||||
|
||||
taosFreeQall(qall);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int retrieveAuthInfo(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey) {
|
||||
// app shall retrieve the auth info based on meterID from DB or a data file
|
||||
// demo code here only for simple demo
|
||||
int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void processResponse(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
sDebug("processResponse ... ");
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
|
||||
static void processRequestMsg(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
SSyncIO *io = pParent;
|
||||
SRpcMsg *pTemp;
|
||||
|
||||
pTemp = taosAllocateQitem(sizeof(SRpcMsg));
|
||||
memcpy(pTemp, pMsg, sizeof(SRpcMsg));
|
||||
|
||||
sDebug("request is received, type:%d, contLen:%d, item:%p", pMsg->msgType, pMsg->contLen, pTemp);
|
||||
taosWriteQitem(io->pMsgQ, pTemp);
|
||||
}
|
||||
|
||||
SSyncIO *syncIOCreate() {
|
||||
SSyncIO *io = (SSyncIO *)malloc(sizeof(SSyncIO));
|
||||
memset(io, 0, sizeof(*io));
|
||||
|
||||
io->pMsgQ = taosOpenQueue();
|
||||
io->pQset = taosOpenQset();
|
||||
taosAddIntoQset(io->pQset, io->pMsgQ, NULL);
|
||||
|
||||
io->start = doSyncIOStart;
|
||||
io->stop = doSyncIOStop;
|
||||
io->ping = doSyncIOPing;
|
||||
io->onMessage = doSyncIOOnMessage;
|
||||
io->destroy = doSyncIODestroy;
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
static int32_t doSyncIOStart(SSyncIO *io) {
|
||||
taosBlockSIGPIPE();
|
||||
|
||||
tsRpcForceTcp = 1;
|
||||
|
||||
// cient rpc init
|
||||
{
|
||||
SRpcInit rpcInit;
|
||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||
rpcInit.localPort = 0;
|
||||
rpcInit.label = "SYNC-IO-CLIENT";
|
||||
rpcInit.numOfThreads = 1;
|
||||
rpcInit.cfp = processResponse;
|
||||
rpcInit.sessions = 100;
|
||||
rpcInit.idleTime = 100;
|
||||
rpcInit.user = "sync-io";
|
||||
rpcInit.secret = "sync-io";
|
||||
rpcInit.ckey = "key";
|
||||
rpcInit.spi = 0;
|
||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||
|
||||
io->clientRpc = rpcOpen(&rpcInit);
|
||||
if (io->clientRpc == NULL) {
|
||||
sError("failed to initialize RPC");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// server rpc init
|
||||
{
|
||||
SRpcInit rpcInit;
|
||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||
rpcInit.localPort = 38000;
|
||||
rpcInit.label = "SYNC-IO-SERVER";
|
||||
rpcInit.numOfThreads = 1;
|
||||
rpcInit.cfp = processRequestMsg;
|
||||
rpcInit.sessions = 1000;
|
||||
rpcInit.idleTime = 2 * 1500;
|
||||
rpcInit.afp = retrieveAuthInfo;
|
||||
rpcInit.parent = io;
|
||||
rpcInit.connType = TAOS_CONN_SERVER;
|
||||
|
||||
void *pRpc = rpcOpen(&rpcInit);
|
||||
if (pRpc == NULL) {
|
||||
sError("failed to start RPC server");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
io->epSet.inUse = 0;
|
||||
addEpIntoEpSet(&io->epSet, "127.0.0.1", 38000);
|
||||
|
||||
// start consumer thread
|
||||
{
|
||||
if (pthread_create(&io->tid, NULL, syncConsumer, io) != 0) {
|
||||
sError("failed to create sync consumer thread since %s", strerror(errno));
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// start tmr thread
|
||||
io->syncTimerManager = taosTmrInit(1000, 50, 10000, "SYNC");
|
||||
io->syncTimer = taosTmrStart(syncTick, 1000, io, io->syncTimerManager);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t doSyncIOStop(SSyncIO *io) {
|
||||
atomic_store_8(&io->isStart, 0);
|
||||
pthread_join(io->tid, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t doSyncIOPing(SSyncIO *io) {
|
||||
SRpcMsg rpcMsg, rspMsg;
|
||||
|
||||
rpcMsg.pCont = rpcMallocCont(10);
|
||||
snprintf(rpcMsg.pCont, 10, "ping");
|
||||
rpcMsg.contLen = 10;
|
||||
rpcMsg.handle = NULL;
|
||||
rpcMsg.msgType = 1;
|
||||
|
||||
rpcSendRequest(io->clientRpc, &io->epSet, &rpcMsg, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t doSyncIOOnMessage(struct SSyncIO *io, void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet) { return 0; }
|
||||
|
||||
static int32_t doSyncIODestroy(SSyncIO *io) {
|
||||
int8_t start = atomic_load_8(&io->isStart);
|
||||
assert(start == 0);
|
||||
|
||||
if (io->serverRpc != NULL) {
|
||||
free(io->serverRpc);
|
||||
io->serverRpc = NULL;
|
||||
}
|
||||
|
||||
if (io->clientRpc != NULL) {
|
||||
free(io->clientRpc);
|
||||
io->clientRpc = NULL;
|
||||
}
|
||||
|
||||
if (io->pMsgQ != NULL) {
|
||||
free(io->pMsgQ);
|
||||
io->pMsgQ = NULL;
|
||||
}
|
||||
|
||||
if (io->pQset != NULL) {
|
||||
free(io->pQset);
|
||||
io->pQset = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -38,6 +38,7 @@ ESyncState syncGetMyRole(int64_t rid) { return TAOS_SYNC_STATE_LEADER; }
|
|||
|
||||
void syncGetNodesRole(int64_t rid, SNodesRole* pNodeRole) {}
|
||||
|
||||
|
||||
SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) {
|
||||
SSyncNode* pSyncNode = (SSyncNode*)malloc(sizeof(SSyncNode));
|
||||
assert(pSyncNode != NULL);
|
||||
|
@ -55,6 +56,7 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) {
|
|||
return pSyncNode;
|
||||
}
|
||||
|
||||
|
||||
void syncNodeClose(SSyncNode* pSyncNode) {
|
||||
assert(pSyncNode != NULL);
|
||||
raftClose(pSyncNode->pRaft);
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "syncMessage.h"
|
||||
#include "sync.h"
|
||||
#include "syncRaft.h"
|
||||
|
||||
void onMessage(SRaft *pRaft, void *pMsg) {}
|
|
@ -13,4 +13,4 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sync.h"
|
||||
#include "syncOnMessage.h"
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sync.h"
|
||||
#include "syncRaftEntry.h"
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "syncRaftLog.h"
|
||||
#include "sync.h"
|
||||
|
||||
int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncBuffer* pBuf) { return 0; }
|
||||
|
||||
|
|
|
@ -14,12 +14,118 @@
|
|||
*/
|
||||
|
||||
#include "syncRaftStore.h"
|
||||
#include "sync.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
int32_t currentTerm(SyncTerm *pCurrentTerm) { return 0; }
|
||||
SRaftStore *raftStoreOpen(const char *path) {
|
||||
int32_t ret;
|
||||
|
||||
int32_t persistCurrentTerm(SyncTerm currentTerm) { return 0; }
|
||||
SRaftStore *pRaftStore = malloc(sizeof(SRaftStore));
|
||||
if (pRaftStore == NULL) {
|
||||
sError("raftStoreOpen malloc error");
|
||||
return NULL;
|
||||
}
|
||||
memset(pRaftStore, 0, sizeof(*pRaftStore));
|
||||
snprintf(pRaftStore->path, sizeof(pRaftStore->path), "%s", path);
|
||||
|
||||
int32_t voteFor(SRaftId *pRaftId) { return 0; }
|
||||
char storeBuf[RAFT_STORE_BLOCK_SIZE];
|
||||
memset(storeBuf, 0, sizeof(storeBuf));
|
||||
|
||||
int32_t persistVoteFor(SRaftId *pRaftId) { return 0; }
|
||||
if (!raftStoreFileExist(pRaftStore->path)) {
|
||||
ret = raftStoreInit(pRaftStore);
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
pRaftStore->fd = taosOpenFileReadWrite(pRaftStore->path);
|
||||
if (pRaftStore->fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int len = taosReadFile(pRaftStore->fd, storeBuf, sizeof(storeBuf));
|
||||
assert(len == RAFT_STORE_BLOCK_SIZE);
|
||||
|
||||
ret = raftStoreDeserialize(pRaftStore, storeBuf, len);
|
||||
assert(ret == 0);
|
||||
|
||||
return pRaftStore;
|
||||
}
|
||||
|
||||
static int32_t raftStoreInit(SRaftStore *pRaftStore) {
|
||||
pRaftStore->fd = taosOpenFileCreateWrite(pRaftStore->path);
|
||||
if (pRaftStore->fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pRaftStore->currentTerm = 0;
|
||||
pRaftStore->voteFor.addr = 0;
|
||||
pRaftStore->voteFor.vgId = 0;
|
||||
|
||||
int32_t ret = raftStorePersist(pRaftStore);
|
||||
assert(ret == 0);
|
||||
|
||||
taosCloseFile(pRaftStore->fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t raftStoreClose(SRaftStore *pRaftStore) {
|
||||
taosCloseFile(pRaftStore->fd);
|
||||
free(pRaftStore);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t raftStorePersist(SRaftStore *pRaftStore) {
|
||||
int32_t ret;
|
||||
char storeBuf[RAFT_STORE_BLOCK_SIZE];
|
||||
|
||||
ret = raftStoreSerialize(pRaftStore, storeBuf, sizeof(storeBuf));
|
||||
assert(ret == 0);
|
||||
|
||||
taosLSeekFile(pRaftStore->fd, 0, SEEK_SET);
|
||||
|
||||
ret = taosWriteFile(pRaftStore->fd, storeBuf, sizeof(storeBuf));
|
||||
assert(ret == RAFT_STORE_BLOCK_SIZE);
|
||||
|
||||
fsync(pRaftStore->fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool raftStoreFileExist(char *path) { return taosStatFile(path, NULL, NULL) >= 0; }
|
||||
|
||||
int32_t raftStoreSerialize(SRaftStore *pRaftStore, char *buf, size_t len) {
|
||||
cJSON *pRoot = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(pRoot, "current_term", pRaftStore->currentTerm);
|
||||
cJSON_AddNumberToObject(pRoot, "vote_for_addr", pRaftStore->voteFor.addr);
|
||||
cJSON_AddNumberToObject(pRoot, "vote_for_vgid", pRaftStore->voteFor.vgId);
|
||||
|
||||
char *serialized = cJSON_Print(pRoot);
|
||||
int len2 = strlen(serialized);
|
||||
assert(len2 < len);
|
||||
memset(buf, 0, len);
|
||||
snprintf(buf, len, "%s", serialized);
|
||||
free(serialized);
|
||||
|
||||
cJSON_Delete(pRoot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t raftStoreDeserialize(SRaftStore *pRaftStore, char *buf, size_t len) {
|
||||
assert(len > 0 && len <= RAFT_STORE_BLOCK_SIZE);
|
||||
cJSON *pRoot = cJSON_Parse(buf);
|
||||
|
||||
cJSON *pCurrentTerm = cJSON_GetObjectItem(pRoot, "current_term");
|
||||
pRaftStore->currentTerm = pCurrentTerm->valueint;
|
||||
|
||||
cJSON *pVoteForAddr = cJSON_GetObjectItem(pRoot, "vote_for_addr");
|
||||
pRaftStore->voteFor.addr = pVoteForAddr->valueint;
|
||||
|
||||
cJSON *pVoteForVgid = cJSON_GetObjectItem(pRoot, "vote_for_vgid");
|
||||
pRaftStore->voteFor.vgId = pVoteForVgid->valueint;
|
||||
|
||||
cJSON_Delete(pRoot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void raftStorePrint(SRaftStore *pRaftStore) {
|
||||
char storeBuf[RAFT_STORE_BLOCK_SIZE];
|
||||
raftStoreSerialize(pRaftStore, storeBuf, sizeof(storeBuf));
|
||||
printf("%s\n", storeBuf);
|
||||
}
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sync.h"
|
||||
#include "syncReplication.h"
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "syncRequestVote.h"
|
||||
#include "sync.h"
|
||||
|
||||
void requestVote(SRaft *pRaft, const SyncRequestVote *pMsg) {
|
||||
// TLA+ Spec
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "syncRequestVoteReply.h"
|
||||
#include "sync.h"
|
||||
|
||||
void onRequestVoteReply(SRaft *pRaft, const SyncRequestVoteReply *pMsg) {
|
||||
// TLA+ Spec
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include "syncSnapshot.h"
|
||||
#include "sync.h"
|
||||
#include "syncRaft.h"
|
||||
|
||||
int32_t takeSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot) { return 0; }
|
||||
|
|
|
@ -14,6 +14,5 @@
|
|||
*/
|
||||
|
||||
#include "syncTimeout.h"
|
||||
#include "sync.h"
|
||||
|
||||
void onTimeout(SRaft *pRaft, void *pMsg) {}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "syncVoteMgr.h"
|
|
@ -0,0 +1,55 @@
|
|||
add_executable(syncTest "")
|
||||
add_executable(syncEnvTest "")
|
||||
add_executable(syncPingTest "")
|
||||
|
||||
|
||||
target_sources(syncTest
|
||||
PRIVATE
|
||||
"syncTest.cpp"
|
||||
)
|
||||
target_sources(syncEnvTest
|
||||
PRIVATE
|
||||
"syncEnvTest.cpp"
|
||||
)
|
||||
target_sources(syncPingTest
|
||||
PRIVATE
|
||||
"syncPingTest.cpp"
|
||||
)
|
||||
|
||||
|
||||
target_include_directories(syncTest
|
||||
PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include/libs/sync"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||
)
|
||||
target_include_directories(syncEnvTest
|
||||
PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include/libs/sync"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||
)
|
||||
target_include_directories(syncPingTest
|
||||
PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include/libs/sync"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries(syncTest
|
||||
sync
|
||||
gtest_main
|
||||
)
|
||||
target_link_libraries(syncEnvTest
|
||||
sync
|
||||
gtest_main
|
||||
)
|
||||
target_link_libraries(syncPingTest
|
||||
sync
|
||||
gtest_main
|
||||
)
|
||||
|
||||
|
||||
enable_testing()
|
||||
add_test(
|
||||
NAME sync_test
|
||||
COMMAND syncTest
|
||||
)
|
|
@ -0,0 +1,56 @@
|
|||
#include "syncEnv.h"
|
||||
#include <stdio.h>
|
||||
#include "syncIO.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaftStore.h"
|
||||
|
||||
void logTest() {
|
||||
sTrace("--- sync log test: trace");
|
||||
sDebug("--- sync log test: debug");
|
||||
sInfo("--- sync log test: info");
|
||||
sWarn("--- sync log test: warn");
|
||||
sError("--- sync log test: error");
|
||||
sFatal("--- sync log test: fatal");
|
||||
}
|
||||
|
||||
void doSync() {
|
||||
SSyncInfo syncInfo;
|
||||
syncInfo.vgId = 1;
|
||||
|
||||
SSyncCfg* pCfg = &syncInfo.syncCfg;
|
||||
pCfg->replicaNum = 3;
|
||||
|
||||
pCfg->nodeInfo[0].nodePort = 7010;
|
||||
taosGetFqdn(pCfg->nodeInfo[0].nodeFqdn);
|
||||
|
||||
pCfg->nodeInfo[1].nodePort = 7110;
|
||||
taosGetFqdn(pCfg->nodeInfo[1].nodeFqdn);
|
||||
|
||||
pCfg->nodeInfo[2].nodePort = 7210;
|
||||
taosGetFqdn(pCfg->nodeInfo[2].nodeFqdn);
|
||||
|
||||
SSyncNode* pSyncNode = syncNodeOpen(&syncInfo);
|
||||
assert(pSyncNode != NULL);
|
||||
}
|
||||
|
||||
int main() {
|
||||
taosInitLog((char*)"syncEnvTest.log", 100000, 10);
|
||||
tsAsyncLog = 0;
|
||||
sDebugFlag = 143 + 64;
|
||||
|
||||
logTest();
|
||||
|
||||
int32_t ret = syncIOStart();
|
||||
assert(ret == 0);
|
||||
|
||||
ret = syncEnvStart();
|
||||
assert(ret == 0);
|
||||
|
||||
doSync();
|
||||
|
||||
while (1) {
|
||||
taosMsleep(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
#include <stdio.h>
|
||||
#include "syncEnv.h"
|
||||
#include "syncIO.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaftStore.h"
|
||||
|
||||
void logTest() {
|
||||
sTrace("--- sync log test: trace");
|
||||
sDebug("--- sync log test: debug");
|
||||
sInfo("--- sync log test: info");
|
||||
sWarn("--- sync log test: warn");
|
||||
sError("--- sync log test: error");
|
||||
sFatal("--- sync log test: fatal");
|
||||
}
|
||||
|
||||
void doSync() {
|
||||
SSyncInfo syncInfo;
|
||||
syncInfo.vgId = 1;
|
||||
|
||||
SSyncCfg* pCfg = &syncInfo.syncCfg;
|
||||
pCfg->myIndex = 0;
|
||||
pCfg->replicaNum = 3;
|
||||
|
||||
pCfg->nodeInfo[0].nodePort = 7010;
|
||||
taosGetFqdn(pCfg->nodeInfo[0].nodeFqdn);
|
||||
|
||||
pCfg->nodeInfo[1].nodePort = 7110;
|
||||
taosGetFqdn(pCfg->nodeInfo[1].nodeFqdn);
|
||||
|
||||
pCfg->nodeInfo[2].nodePort = 7210;
|
||||
taosGetFqdn(pCfg->nodeInfo[2].nodeFqdn);
|
||||
|
||||
SSyncNode* pSyncNode = syncNodeOpen(&syncInfo);
|
||||
assert(pSyncNode != NULL);
|
||||
}
|
||||
|
||||
int main() {
|
||||
taosInitLog((char*)"syncPingTest.log", 100000, 10);
|
||||
tsAsyncLog = 0;
|
||||
sDebugFlag = 143 + 64;
|
||||
|
||||
logTest();
|
||||
|
||||
int32_t ret = syncIOStart();
|
||||
assert(ret == 0);
|
||||
|
||||
ret = syncEnvStart();
|
||||
assert(ret == 0);
|
||||
|
||||
doSync();
|
||||
|
||||
while (1) {
|
||||
taosMsleep(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,7 +1,57 @@
|
|||
#include <stdio.h>
|
||||
#include "syncIO.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaftStore.h"
|
||||
|
||||
int main() {
|
||||
printf("test \n");
|
||||
return 0;
|
||||
void *pingFunc(void *param) {
|
||||
SSyncIO *io = (SSyncIO *)param;
|
||||
while (1) {
|
||||
sDebug("io->ping");
|
||||
io->ping(io);
|
||||
sleep(1);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main() {
|
||||
taosInitLog((char *)"syncTest.log", 100000, 10);
|
||||
tsAsyncLog = 0;
|
||||
sDebugFlag = 143 + 64;
|
||||
|
||||
sTrace("sync log test: trace");
|
||||
sDebug("sync log test: debug");
|
||||
sInfo("sync log test: info");
|
||||
sWarn("sync log test: warn");
|
||||
sError("sync log test: error");
|
||||
sFatal("sync log test: fatal");
|
||||
|
||||
SRaftStore *pRaftStore = raftStoreOpen("./raft_store.json");
|
||||
assert(pRaftStore != NULL);
|
||||
|
||||
raftStorePrint(pRaftStore);
|
||||
|
||||
pRaftStore->currentTerm = 100;
|
||||
pRaftStore->voteFor.addr = 200;
|
||||
pRaftStore->voteFor.vgId = 300;
|
||||
|
||||
raftStorePrint(pRaftStore);
|
||||
|
||||
raftStorePersist(pRaftStore);
|
||||
|
||||
sDebug("sync test");
|
||||
|
||||
SSyncIO *syncIO = syncIOCreate();
|
||||
assert(syncIO != NULL);
|
||||
|
||||
syncIO->start(syncIO);
|
||||
|
||||
sleep(2);
|
||||
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, pingFunc, syncIO);
|
||||
|
||||
while (1) {
|
||||
sleep(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue