fix bug
This commit is contained in:
parent
adb813f09e
commit
4c19f56686
|
@ -47,13 +47,13 @@ option(
|
|||
option(
|
||||
BUILD_WITH_UV
|
||||
"If build with libuv"
|
||||
OFF
|
||||
ON
|
||||
)
|
||||
|
||||
option(
|
||||
BUILD_WITH_UV_TRANS
|
||||
"If build with libuv_trans "
|
||||
OFF
|
||||
ON
|
||||
)
|
||||
|
||||
option(
|
||||
|
|
|
@ -64,6 +64,7 @@ typedef struct SRpcInit {
|
|||
int8_t connType; // TAOS_CONN_UDP, TAOS_CONN_TCPC, TAOS_CONN_TCPS
|
||||
int idleTime; // milliseconds, 0 means idle timer is disabled
|
||||
|
||||
bool noPool; // create conn pool or not
|
||||
// the following is for client app ecurity only
|
||||
char *user; // user name
|
||||
char spi; // security parameter index
|
||||
|
|
|
@ -192,6 +192,7 @@ static int32_t dndInitClient(SDnode *pDnode) {
|
|||
rpcInit.ckey = INTERNAL_CKEY;
|
||||
rpcInit.spi = 1;
|
||||
rpcInit.parent = pDnode;
|
||||
rpcInit.noPool = true;
|
||||
|
||||
char pass[TSDB_PASSWORD_LEN + 1] = {0};
|
||||
taosEncryptPass_c((uint8_t *)(INTERNAL_SECRET), strlen(INTERNAL_SECRET), pass);
|
||||
|
|
|
@ -21,13 +21,18 @@ class TestClient {
|
|||
bool Init(const char* user, const char* pass, const char* fqdn, uint16_t port);
|
||||
void Cleanup();
|
||||
|
||||
void DoInit();
|
||||
|
||||
SRpcMsg* SendReq(SRpcMsg* pReq);
|
||||
void SetRpcRsp(SRpcMsg* pRsp);
|
||||
tsem_t* GetSem();
|
||||
void Restart();
|
||||
|
||||
private:
|
||||
char fqdn[TSDB_FQDN_LEN];
|
||||
uint16_t port;
|
||||
char user[128];
|
||||
char pass[128];
|
||||
void* clientRpc;
|
||||
SRpcMsg* pRsp;
|
||||
tsem_t sem;
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#include "os.h"
|
||||
|
||||
#include "dnode.h"
|
||||
#include "tmsg.h"
|
||||
#include "tconfig.h"
|
||||
#include "tdataformat.h"
|
||||
#include "tglobal.h"
|
||||
#include "tmsg.h"
|
||||
#include "tnote.h"
|
||||
#include "trpc.h"
|
||||
#include "tthread.h"
|
||||
|
@ -39,6 +39,7 @@ class Testbase {
|
|||
void Restart();
|
||||
void ServerStop();
|
||||
void ServerStart();
|
||||
void ClientRestart();
|
||||
SRpcMsg* SendReq(tmsg_t msgType, void* pCont, int32_t contLen);
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,33 +13,38 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tep.h"
|
||||
#include "sut.h"
|
||||
#include "tep.h"
|
||||
|
||||
static void processClientRsp(void* parent, SRpcMsg* pRsp, SEpSet* pEpSet) {
|
||||
TestClient* client = (TestClient*)parent;
|
||||
client->SetRpcRsp(pRsp);
|
||||
uInfo("response:%s from dnode, code:0x%x", TMSG_INFO(pRsp->msgType), pRsp->code);
|
||||
uInfo("x response:%s from dnode, code:0x%x, msgSize: %d", TMSG_INFO(pRsp->msgType), pRsp->code, pRsp->contLen);
|
||||
tsem_post(client->GetSem());
|
||||
}
|
||||
|
||||
void TestClient::SetRpcRsp(SRpcMsg* pRsp) { this->pRsp = pRsp; };
|
||||
void TestClient::SetRpcRsp(SRpcMsg* rsp) {
|
||||
this->pRsp = (SRpcMsg*)calloc(1, sizeof(SRpcMsg));
|
||||
this->pRsp->msgType = rsp->msgType;
|
||||
this->pRsp->code = rsp->code;
|
||||
this->pRsp->pCont = rsp->pCont;
|
||||
this->pRsp->contLen = rsp->contLen;
|
||||
};
|
||||
|
||||
tsem_t* TestClient::GetSem() { return &sem; }
|
||||
|
||||
bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint16_t port) {
|
||||
void TestClient::DoInit() {
|
||||
char secretEncrypt[TSDB_PASSWORD_LEN + 1] = {0};
|
||||
taosEncryptPass_c((uint8_t*)pass, strlen(pass), secretEncrypt);
|
||||
|
||||
SRpcInit rpcInit;
|
||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||
rpcInit.label = (char*)"DND-C";
|
||||
rpcInit.label = (char*)"shell";
|
||||
rpcInit.numOfThreads = 1;
|
||||
rpcInit.cfp = processClientRsp;
|
||||
rpcInit.sessions = 1024;
|
||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||
rpcInit.idleTime = 30 * 1000;
|
||||
rpcInit.user = (char*)user;
|
||||
rpcInit.user = (char*)this->user;
|
||||
rpcInit.ckey = (char*)"key";
|
||||
rpcInit.parent = this;
|
||||
rpcInit.secret = (char*)secretEncrypt;
|
||||
|
@ -47,11 +52,16 @@ bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint
|
|||
|
||||
clientRpc = rpcOpen(&rpcInit);
|
||||
ASSERT(clientRpc);
|
||||
tsem_init(&this->sem, 0, 0);
|
||||
}
|
||||
|
||||
tsem_init(&sem, 0, 0);
|
||||
bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint16_t port) {
|
||||
strcpy(this->fqdn, fqdn);
|
||||
strcpy(this->user, user);
|
||||
strcpy(this->pass, pass);
|
||||
this->port = port;
|
||||
|
||||
// this->pRsp = NULL;
|
||||
this->DoInit();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -60,11 +70,16 @@ void TestClient::Cleanup() {
|
|||
rpcClose(clientRpc);
|
||||
}
|
||||
|
||||
void TestClient::Restart() {
|
||||
this->Cleanup();
|
||||
this->DoInit();
|
||||
}
|
||||
SRpcMsg* TestClient::SendReq(SRpcMsg* pReq) {
|
||||
SEpSet epSet = {0};
|
||||
addEpIntoEpSet(&epSet, fqdn, port);
|
||||
rpcSendRequest(clientRpc, &epSet, pReq, NULL);
|
||||
tsem_wait(&sem);
|
||||
uInfo("y response:%s from dnode, code:0x%x, msgSize: %d", TMSG_INFO(pRsp->msgType), pRsp->code, pRsp->contLen);
|
||||
|
||||
return pRsp;
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ void Testbase::InitLog(const char* path) {
|
|||
mDebugFlag = 143;
|
||||
cDebugFlag = 0;
|
||||
jniDebugFlag = 0;
|
||||
tmrDebugFlag = 0;
|
||||
uDebugFlag = 0;
|
||||
rpcDebugFlag = 0;
|
||||
tmrDebugFlag = 143;
|
||||
uDebugFlag = 143;
|
||||
rpcDebugFlag = 143;
|
||||
qDebugFlag = 0;
|
||||
wDebugFlag = 0;
|
||||
sDebugFlag = 0;
|
||||
|
@ -66,16 +66,21 @@ void Testbase::Init(const char* path, int16_t port) {
|
|||
|
||||
void Testbase::Cleanup() {
|
||||
tFreeSTableMetaRsp(&metaRsp);
|
||||
server.Stop();
|
||||
client.Cleanup();
|
||||
taosMsleep(10);
|
||||
server.Stop();
|
||||
dndCleanup();
|
||||
}
|
||||
|
||||
void Testbase::Restart() { server.Restart(); }
|
||||
void Testbase::Restart() {
|
||||
server.Restart();
|
||||
client.Restart();
|
||||
}
|
||||
|
||||
void Testbase::ServerStop() { server.Stop(); }
|
||||
|
||||
void Testbase::ServerStart() { server.DoStart(); }
|
||||
void Testbase::ClientRestart() { client.Restart(); }
|
||||
|
||||
SRpcMsg* Testbase::SendReq(tmsg_t msgType, void* pCont, int32_t contLen) {
|
||||
SRpcMsg rpcMsg = {0};
|
||||
|
|
|
@ -404,7 +404,8 @@ SMnodeMsg *mndInitMsg(SMnode *pMnode, SRpcMsg *pRpcMsg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (pRpcMsg->msgType != TDMT_MND_TRANS && pRpcMsg->msgType != TDMT_MND_MQ_TIMER && pRpcMsg->msgType != TDMT_MND_MQ_DO_REBALANCE) {
|
||||
if (pRpcMsg->msgType != TDMT_MND_TRANS && pRpcMsg->msgType != TDMT_MND_MQ_TIMER &&
|
||||
pRpcMsg->msgType != TDMT_MND_MQ_DO_REBALANCE) {
|
||||
SRpcConnInfo connInfo = {0};
|
||||
if ((pRpcMsg->msgType & 1U) && rpcGetConnInfo(pRpcMsg->handle, &connInfo) != 0) {
|
||||
taosFreeQitem(pMsg);
|
||||
|
|
|
@ -190,6 +190,9 @@ TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) {
|
|||
tSerializeSMCreateDropQSBNodeReq(pReq, contLen, &createReq);
|
||||
|
||||
server2.Stop();
|
||||
taosMsleep(1000);
|
||||
// test.ClientRestart();
|
||||
|
||||
SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen);
|
||||
ASSERT_NE(pRsp, nullptr);
|
||||
ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL);
|
||||
|
@ -226,6 +229,7 @@ TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) {
|
|||
{
|
||||
// server start, wait until the rollback finished
|
||||
server2.DoStart();
|
||||
test.ClientRestart();
|
||||
taosMsleep(1000);
|
||||
|
||||
int32_t retry = 0;
|
||||
|
@ -248,7 +252,6 @@ TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) {
|
|||
ASSERT_NE(retry, retryMax);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MndTestQnode, 04_Drop_Qnode_Rollback) {
|
||||
{
|
||||
// send message first, then dnode2 crash, result is returned, and rollback is started
|
||||
|
|
|
@ -46,8 +46,10 @@ class MndTestTrans : public ::testing::Test {
|
|||
free(buffer);
|
||||
taosFsyncFile(fd);
|
||||
taosCloseFile(fd);
|
||||
taosMsleep(1000);
|
||||
|
||||
test.ServerStart();
|
||||
test.ClientRestart();
|
||||
}
|
||||
|
||||
static Testbase test;
|
||||
|
|
|
@ -617,6 +617,7 @@ TEST_F(MndTestUser, 06_Create_Drop_Alter_User) {
|
|||
// restart
|
||||
test.Restart();
|
||||
|
||||
taosMsleep(1000);
|
||||
test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, "");
|
||||
CHECK_META("show users", 4);
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ typedef struct SConnBuffer {
|
|||
char* buf;
|
||||
int len;
|
||||
int cap;
|
||||
int left;
|
||||
int total;
|
||||
} SConnBuffer;
|
||||
|
||||
typedef void (*AsyncCB)(uv_async_t* handle);
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct {
|
|||
int8_t connType;
|
||||
int64_t index;
|
||||
char label[TSDB_LABEL_LEN];
|
||||
bool noPool; // pool or not
|
||||
|
||||
char user[TSDB_UNI_LEN]; // meter ID
|
||||
char spi; // security parameter index
|
||||
|
|
|
@ -64,6 +64,7 @@ typedef struct {
|
|||
void (*cfp)(void *parent, SRpcMsg *, SEpSet *);
|
||||
int (*afp)(void *parent, char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
||||
|
||||
bool noPool;
|
||||
int32_t refCount;
|
||||
void * parent;
|
||||
void * idPool; // handle to ID pool
|
||||
|
|
|
@ -27,7 +27,7 @@ void* rpcOpen(const SRpcInit* pInit) {
|
|||
return NULL;
|
||||
}
|
||||
if (pInit->label) {
|
||||
tstrncpy(pRpc->label, pInit->label, strlen(pInit->label));
|
||||
tstrncpy(pRpc->label, pInit->label, strlen(pInit->label) + 1);
|
||||
}
|
||||
pRpc->cfp = pInit->cfp;
|
||||
if (pInit->connType == TAOS_CONN_SERVER) {
|
||||
|
@ -35,6 +35,8 @@ void* rpcOpen(const SRpcInit* pInit) {
|
|||
} else {
|
||||
pRpc->numOfThreads = pInit->numOfThreads;
|
||||
}
|
||||
|
||||
pRpc->noPool = pInit->noPool;
|
||||
pRpc->connType = pInit->connType;
|
||||
pRpc->idleTime = pInit->idleTime;
|
||||
pRpc->tcphandle = (*taosInitHandle[pRpc->connType])(0, pInit->localPort, pRpc->label, pRpc->numOfThreads, NULL, pRpc);
|
||||
|
|
|
@ -126,6 +126,9 @@ static void clientHandleResp(SCliConn* conn) {
|
|||
pHead->code = htonl(pHead->code);
|
||||
pHead->msgLen = htonl(pHead->msgLen);
|
||||
|
||||
// buf's mem alread translated to rpcMsg.pCont
|
||||
transClearBuffer(&conn->readBuf);
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
rpcMsg.contLen = transContLenFromMsg(pHead->msgLen);
|
||||
rpcMsg.pCont = transContFromHead((char*)pHead);
|
||||
|
@ -140,9 +143,9 @@ static void clientHandleResp(SCliConn* conn) {
|
|||
tDebug("client conn %p persist by app", conn);
|
||||
}
|
||||
|
||||
tDebug("client conn %p %s received from %s:%d, local info: %s:%d", conn, TMSG_INFO(pHead->msgType),
|
||||
inet_ntoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port), inet_ntoa(conn->locaddr.sin_addr),
|
||||
ntohs(conn->locaddr.sin_port));
|
||||
tDebug("%s client conn %p %s received from %s:%d, local info: %s:%d, msg size: %d", pRpc->label, conn,
|
||||
TMSG_INFO(pHead->msgType), inet_ntoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port),
|
||||
inet_ntoa(conn->locaddr.sin_addr), ntohs(conn->locaddr.sin_port), rpcMsg.contLen);
|
||||
|
||||
conn->secured = pHead->secured;
|
||||
if (conn->push != NULL && conn->ctnRdCnt != 0) {
|
||||
|
@ -150,27 +153,27 @@ static void clientHandleResp(SCliConn* conn) {
|
|||
conn->push = NULL;
|
||||
} else {
|
||||
if (pCtx->pSem == NULL) {
|
||||
tTrace("client conn %p handle resp", conn);
|
||||
tTrace("%s client conn %p handle resp", pRpc->label, conn);
|
||||
(pRpc->cfp)(pRpc->parent, &rpcMsg, NULL);
|
||||
} else {
|
||||
tTrace("client conn(sync) %p handle resp", conn);
|
||||
tTrace("%s client conn(sync) %p handle resp", pRpc->label, conn);
|
||||
memcpy((char*)pCtx->pRsp, (char*)&rpcMsg, sizeof(rpcMsg));
|
||||
tsem_post(pCtx->pSem);
|
||||
}
|
||||
}
|
||||
conn->ctnRdCnt += 1;
|
||||
|
||||
// buf's mem alread translated to rpcMsg.pCont
|
||||
transClearBuffer(&conn->readBuf);
|
||||
|
||||
uv_read_start((uv_stream_t*)conn->stream, clientAllocBufferCb, clientReadCb);
|
||||
|
||||
SCliThrdObj* pThrd = conn->hostThrd;
|
||||
|
||||
// user owns conn->persist = 1
|
||||
if (conn->push == NULL && conn->persist == 0) {
|
||||
if (pRpc->noPool == true) {
|
||||
} else {
|
||||
addConnToPool(pThrd->pool, pCtx->ip, pCtx->port, conn);
|
||||
}
|
||||
}
|
||||
destroyCmsg(conn->data);
|
||||
conn->data = NULL;
|
||||
// start thread's timer of conn pool if not active
|
||||
|
@ -184,7 +187,6 @@ static void clientHandleExcept(SCliConn* pConn) {
|
|||
clientConnDestroy(pConn, true);
|
||||
return;
|
||||
}
|
||||
tTrace("client conn %p start to destroy", pConn);
|
||||
SCliMsg* pMsg = pConn->data;
|
||||
|
||||
tmsg_t msgType = TDMT_MND_CONNECT;
|
||||
|
@ -213,6 +215,7 @@ static void clientHandleExcept(SCliConn* pConn) {
|
|||
}
|
||||
pConn->push = NULL;
|
||||
}
|
||||
tTrace("%s client conn %p start to destroy", pCtx->pTransInst->label, pConn);
|
||||
if (pConn->push == NULL) {
|
||||
destroyCmsg(pConn->data);
|
||||
pConn->data = NULL;
|
||||
|
@ -226,7 +229,7 @@ static void clientTimeoutCb(uv_timer_t* handle) {
|
|||
SCliThrdObj* pThrd = handle->data;
|
||||
SRpcInfo* pRpc = pThrd->pTransInst;
|
||||
int64_t currentTime = pThrd->nextTimeout;
|
||||
tTrace("client conn timeout, try to remove expire conn from conn pool");
|
||||
tTrace("%s, client conn timeout, try to remove expire conn from conn pool", pRpc->label);
|
||||
|
||||
SConnList* p = taosHashIterate((SHashObj*)pThrd->pool, NULL);
|
||||
while (p != NULL) {
|
||||
|
@ -307,21 +310,30 @@ static void addConnToPool(void* pool, char* ip, uint32_t port, SCliConn* conn) {
|
|||
QUEUE_PUSH(&plist->conn, &conn->conn);
|
||||
}
|
||||
static bool clientReadComplete(SConnBuffer* data) {
|
||||
if (data->len >= sizeof(STransMsgHead)) {
|
||||
STransMsgHead head;
|
||||
int32_t headLen = sizeof(head);
|
||||
if (data->len >= headLen) {
|
||||
memcpy((char*)&head, data->buf, headLen);
|
||||
int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen);
|
||||
if (msgLen > data->len) {
|
||||
data->left = msgLen - data->len;
|
||||
return false;
|
||||
} else if (msgLen == data->len) {
|
||||
data->left = 0;
|
||||
memcpy((char*)&head, data->buf, sizeof(head));
|
||||
int32_t msgLen = (int32_t)htonl(head.msgLen);
|
||||
data->total = msgLen;
|
||||
}
|
||||
|
||||
if (data->len == data->cap && data->total == data->cap) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// if (data->len >= headLen) {
|
||||
// memcpy((char*)&head, data->buf, headLen);
|
||||
// int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen);
|
||||
// if (msgLen > data->len) {
|
||||
// data->left = msgLen - data->len;
|
||||
// return false;
|
||||
// } else if (msgLen == data->len) {
|
||||
// data->left = 0;
|
||||
// return true;
|
||||
// }
|
||||
//} else {
|
||||
// return false;
|
||||
//}
|
||||
}
|
||||
static void clientAllocBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||
SCliConn* conn = handle->data;
|
||||
|
@ -338,7 +350,7 @@ static void clientReadCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf
|
|||
if (nread > 0) {
|
||||
pBuf->len += nread;
|
||||
if (clientReadComplete(pBuf)) {
|
||||
uv_read_stop((uv_stream_t*)conn->stream);
|
||||
// uv_read_stop((uv_stream_t*)conn->stream);
|
||||
tTrace("client conn %p read complete", conn);
|
||||
clientHandleResp(conn);
|
||||
} else {
|
||||
|
@ -346,6 +358,10 @@ static void clientReadCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (nread == UV_EOF) {
|
||||
tError("client conn %p read error: %s", conn, uv_err_name(nread));
|
||||
clientHandleExcept(conn);
|
||||
}
|
||||
assert(nread <= 0);
|
||||
if (nread == 0) {
|
||||
// ref http://docs.libuv.org/en/v1.x/stream.html?highlight=uv_read_start#c.uv_read_cb
|
||||
|
@ -353,7 +369,7 @@ static void clientReadCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf
|
|||
// read(2).
|
||||
return;
|
||||
}
|
||||
if (nread < 0 || nread == UV_EOF) {
|
||||
if (nread < 0) {
|
||||
tError("client conn %p read error: %s", conn, uv_err_name(nread));
|
||||
clientHandleExcept(conn);
|
||||
}
|
||||
|
@ -467,6 +483,7 @@ static void clientConnCb(uv_connect_t* req, int status) {
|
|||
static void clientHandleQuit(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
||||
tDebug("client work thread %p start to quit", pThrd);
|
||||
destroyCmsg(pMsg);
|
||||
destroyConnPool(pThrd->pool);
|
||||
// transDestroyAsyncPool(pThr) uv_close((uv_handle_t*)pThrd->cliAsync, NULL);
|
||||
uv_timer_stop(pThrd->timer);
|
||||
pThrd->quit = true;
|
||||
|
@ -483,7 +500,10 @@ static void clientHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
|||
|
||||
SCliConn* conn = NULL;
|
||||
if (pMsg->msg.handle == NULL) {
|
||||
if (pCtx->pTransInst->noPool == true) {
|
||||
} else {
|
||||
conn = getConnFromPool(pThrd->pool, pCtx->ip, pCtx->port);
|
||||
}
|
||||
if (conn != NULL) {
|
||||
tTrace("client conn %p get from conn pool", conn);
|
||||
}
|
||||
|
@ -512,7 +532,11 @@ static void clientHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
|||
conn->stream = (uv_stream_t*)malloc(sizeof(uv_tcp_t));
|
||||
uv_tcp_init(pThrd->loop, (uv_tcp_t*)(conn->stream));
|
||||
conn->stream->data = conn;
|
||||
|
||||
uv_tcp_nodelay((uv_tcp_t*)conn->stream, 1);
|
||||
int ret = uv_tcp_keepalive((uv_tcp_t*)conn->stream, 1, 1);
|
||||
if (ret) {
|
||||
tTrace("client conn %p failed to set keepalive, %s", conn, uv_err_name(ret));
|
||||
}
|
||||
// write req handle
|
||||
conn->writeReq = malloc(sizeof(uv_write_t));
|
||||
conn->writeReq->data = conn;
|
||||
|
|
|
@ -205,6 +205,7 @@ int transInitBuffer(SConnBuffer* buf) {
|
|||
}
|
||||
int transClearBuffer(SConnBuffer* buf) {
|
||||
memset(buf, 0, sizeof(*buf));
|
||||
buf->total = -1;
|
||||
return 0;
|
||||
}
|
||||
int transAllocBuffer(SConnBuffer* connBuf, uv_buf_t* uvBuf) {
|
||||
|
@ -214,27 +215,25 @@ int transAllocBuffer(SConnBuffer* connBuf, uv_buf_t* uvBuf) {
|
|||
* |<------STransMsgHead------->|<-------------------userdata--------------->|<-----auth data----->|<----user
|
||||
* info--->|
|
||||
*/
|
||||
static const int CAPACITY = 1024;
|
||||
static const int CAPACITY = sizeof(STransMsgHead);
|
||||
|
||||
SConnBuffer* p = connBuf;
|
||||
if (p->cap == 0) {
|
||||
p->buf = (char*)calloc(CAPACITY, sizeof(char));
|
||||
p->len = 0;
|
||||
p->cap = CAPACITY;
|
||||
p->left = -1;
|
||||
p->total = 0;
|
||||
|
||||
uvBuf->base = p->buf;
|
||||
uvBuf->len = CAPACITY;
|
||||
} else {
|
||||
if (p->len >= p->cap) {
|
||||
if (p->left == -1) {
|
||||
p->cap *= 2;
|
||||
STransMsgHead head;
|
||||
memcpy((char*)&head, p->buf, sizeof(head));
|
||||
int32_t msgLen = (int32_t)htonl(head.msgLen);
|
||||
|
||||
p->total = msgLen;
|
||||
p->cap = msgLen;
|
||||
p->buf = realloc(p->buf, p->cap);
|
||||
} else if (p->len + p->left > p->cap) {
|
||||
p->cap = p->len + p->left;
|
||||
p->buf = realloc(p->buf, p->len + p->left);
|
||||
}
|
||||
}
|
||||
uvBuf->base = p->buf + p->len;
|
||||
uvBuf->len = p->cap - p->len;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ typedef struct SWorkThrdObj {
|
|||
SAsyncPool* asyncPool;
|
||||
// uv_async_t* workerAsync; //
|
||||
queue msg;
|
||||
queue conn;
|
||||
pthread_mutex_t msgMtx;
|
||||
void* pTransInst;
|
||||
} SWorkThrdObj;
|
||||
|
@ -103,7 +104,7 @@ static void uvStartSendResp(SSrvMsg* msg);
|
|||
static void destroySmsg(SSrvMsg* smsg);
|
||||
// check whether already read complete packet
|
||||
static bool readComplete(SConnBuffer* buf);
|
||||
static SSrvConn* createConn();
|
||||
static SSrvConn* createConn(void* hThrd);
|
||||
static void destroyConn(SSrvConn* conn, bool clear /*clear handle or not*/);
|
||||
|
||||
static void uvDestroyConn(uv_handle_t* handle);
|
||||
|
@ -117,11 +118,6 @@ static bool addHandleToWorkloop(void* arg);
|
|||
static bool addHandleToAcceptloop(void* arg);
|
||||
|
||||
void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||
/*
|
||||
* formate of data buffer:
|
||||
* |<--------------------------data from socket------------------------------->|
|
||||
* |<------STransMsgHead------->|<-------------------other data--------------->|
|
||||
*/
|
||||
SSrvConn* conn = handle->data;
|
||||
SConnBuffer* pBuf = &conn->readBuf;
|
||||
transAllocBuffer(pBuf, buf);
|
||||
|
@ -131,23 +127,27 @@ void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* b
|
|||
//
|
||||
static bool readComplete(SConnBuffer* data) {
|
||||
// TODO(yihao): handle pipeline later
|
||||
STransMsgHead head;
|
||||
int32_t headLen = sizeof(head);
|
||||
if (data->len >= headLen) {
|
||||
memcpy((char*)&head, data->buf, headLen);
|
||||
int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen);
|
||||
if (msgLen > data->len) {
|
||||
data->left = msgLen - data->len;
|
||||
return false;
|
||||
} else if (msgLen == data->len) {
|
||||
if (data->len == data->cap && data->total == data->cap) {
|
||||
return true;
|
||||
} else if (msgLen < data->len) {
|
||||
return false;
|
||||
// handle other packet later
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// STransMsgHead head;
|
||||
// int32_t headLen = sizeof(head);
|
||||
// if (data->len >= headLen) {
|
||||
// memcpy((char*)&head, data->buf, headLen);
|
||||
// int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen);
|
||||
// if (msgLen > data->len) {
|
||||
// data->left = msgLen - data->len;
|
||||
// return false;
|
||||
// } else if (msgLen == data->len) {
|
||||
// return true;
|
||||
// } else if (msgLen < data->len) {
|
||||
// return false;
|
||||
// // handle other packet later
|
||||
// }
|
||||
//} else {
|
||||
// return false;
|
||||
//}
|
||||
}
|
||||
|
||||
// static void uvDoProcess(SRecvInfo* pRecv) {
|
||||
|
@ -241,7 +241,7 @@ static void uvHandleReq(SSrvConn* pConn) {
|
|||
}
|
||||
|
||||
pConn->inType = pHead->msgType;
|
||||
assert(transIsReq(pHead->msgType));
|
||||
// assert(transIsReq(pHead->msgType));
|
||||
|
||||
SRpcInfo* pRpc = (SRpcInfo*)p->shandle;
|
||||
pHead->code = htonl(pHead->code);
|
||||
|
@ -266,9 +266,9 @@ static void uvHandleReq(SSrvConn* pConn) {
|
|||
|
||||
transClearBuffer(&pConn->readBuf);
|
||||
pConn->ref++;
|
||||
tDebug("server conn %p %s received from %s:%d, local info: %s:%d", pConn, TMSG_INFO(rpcMsg.msgType),
|
||||
tDebug("server conn %p %s received from %s:%d, local info: %s:%d, msg size: %d", pConn, TMSG_INFO(rpcMsg.msgType),
|
||||
inet_ntoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), inet_ntoa(pConn->locaddr.sin_addr),
|
||||
ntohs(pConn->locaddr.sin_port));
|
||||
ntohs(pConn->locaddr.sin_port), rpcMsg.contLen);
|
||||
(*(pRpc->cfp))(pRpc->parent, &rpcMsg, NULL);
|
||||
// uv_timer_start(pConn->pTimer, uvHandleActivityTimeout, pRpc->idleTime * 10000, 0);
|
||||
// auth
|
||||
|
@ -290,6 +290,14 @@ void uvOnReadCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) {
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (nread == UV_EOF) {
|
||||
tError("server conn %p read error: %s", conn, uv_err_name(nread));
|
||||
if (conn->ref > 1) {
|
||||
conn->ref++; // ref > 1 signed that write is in progress
|
||||
}
|
||||
destroyConn(conn, true);
|
||||
return;
|
||||
}
|
||||
if (nread == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -302,8 +310,8 @@ void uvOnReadCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) {
|
|||
}
|
||||
}
|
||||
void uvAllocConnBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||
buf->base = malloc(sizeof(char));
|
||||
buf->len = 2;
|
||||
buf->base = calloc(1, sizeof(char) * buf->len);
|
||||
}
|
||||
|
||||
void uvOnTimeoutCb(uv_timer_t* handle) {
|
||||
|
@ -386,6 +394,7 @@ static void uvStartSendRespInternal(SSrvMsg* smsg) {
|
|||
static void uvStartSendResp(SSrvMsg* smsg) {
|
||||
// impl
|
||||
SSrvConn* pConn = smsg->pConn;
|
||||
pConn->ref--; //
|
||||
if (taosArrayGetSize(pConn->srvMsgs) > 0) {
|
||||
tDebug("server conn %p push data to client %s:%d, local info: %s:%d", pConn, inet_ntoa(pConn->addr.sin_addr),
|
||||
ntohs(pConn->addr.sin_port), inet_ntoa(pConn->locaddr.sin_addr), ntohs(pConn->locaddr.sin_port));
|
||||
|
@ -403,6 +412,16 @@ static void destroySmsg(SSrvMsg* smsg) {
|
|||
transFreeMsg(smsg->msg.pCont);
|
||||
free(smsg);
|
||||
}
|
||||
static void destroyAllConn(SWorkThrdObj* pThrd) {
|
||||
while (!QUEUE_IS_EMPTY(&pThrd->conn)) {
|
||||
queue* h = QUEUE_HEAD(&pThrd->conn);
|
||||
QUEUE_REMOVE(h);
|
||||
QUEUE_INIT(h);
|
||||
|
||||
SSrvConn* c = QUEUE_DATA(h, SSrvConn, queue);
|
||||
destroyConn(c, true);
|
||||
}
|
||||
}
|
||||
void uvWorkerAsyncCb(uv_async_t* handle) {
|
||||
SAsyncItem* item = handle->data;
|
||||
SWorkThrdObj* pThrd = item->pThrd;
|
||||
|
@ -424,8 +443,9 @@ void uvWorkerAsyncCb(uv_async_t* handle) {
|
|||
continue;
|
||||
}
|
||||
if (msg->pConn == NULL) {
|
||||
//
|
||||
free(msg);
|
||||
|
||||
destroyAllConn(pThrd);
|
||||
uv_stop(pThrd->loop);
|
||||
} else {
|
||||
uvStartSendResp(msg);
|
||||
|
@ -439,6 +459,7 @@ void uvWorkerAsyncCb(uv_async_t* handle) {
|
|||
}
|
||||
static void uvAcceptAsyncCb(uv_async_t* async) {
|
||||
SServerObj* srv = async->data;
|
||||
uv_close((uv_handle_t*)&srv->server, NULL);
|
||||
uv_stop(srv->loop);
|
||||
}
|
||||
|
||||
|
@ -491,7 +512,7 @@ void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) {
|
|||
uv_handle_type pending = uv_pipe_pending_type(pipe);
|
||||
assert(pending == UV_TCP);
|
||||
|
||||
SSrvConn* pConn = createConn();
|
||||
SSrvConn* pConn = createConn(pThrd);
|
||||
|
||||
pConn->pTransInst = pThrd->pTransInst;
|
||||
/* init conn timer*/
|
||||
|
@ -507,6 +528,9 @@ void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) {
|
|||
uv_tcp_init(pThrd->loop, pConn->pTcp);
|
||||
pConn->pTcp->data = pConn;
|
||||
|
||||
uv_tcp_nodelay(pConn->pTcp, 1);
|
||||
uv_tcp_keepalive(pConn->pTcp, 1, 1);
|
||||
|
||||
// init write request, just
|
||||
pConn->pWriter = calloc(1, sizeof(uv_write_t));
|
||||
pConn->pWriter->data = pConn;
|
||||
|
@ -560,6 +584,9 @@ static bool addHandleToWorkloop(void* arg) {
|
|||
QUEUE_INIT(&pThrd->msg);
|
||||
pthread_mutex_init(&pThrd->msgMtx, NULL);
|
||||
|
||||
// conn set
|
||||
QUEUE_INIT(&pThrd->conn);
|
||||
|
||||
pThrd->asyncPool = transCreateAsyncPool(pThrd->loop, 4, pThrd, uvWorkerAsyncCb);
|
||||
uv_read_start((uv_stream_t*)pThrd->pipe, uvAllocConnBufferCb, uvOnConnectionCb);
|
||||
return true;
|
||||
|
@ -598,8 +625,13 @@ void* workerThread(void* arg) {
|
|||
uv_run(pThrd->loop, UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
static SSrvConn* createConn() {
|
||||
static SSrvConn* createConn(void* hThrd) {
|
||||
SWorkThrdObj* pThrd = hThrd;
|
||||
|
||||
SSrvConn* pConn = (SSrvConn*)calloc(1, sizeof(SSrvConn));
|
||||
QUEUE_INIT(&pConn->queue);
|
||||
|
||||
QUEUE_PUSH(&pThrd->conn, &pConn->queue);
|
||||
pConn->srvMsgs = taosArrayInit(2, sizeof(void*)); //
|
||||
tTrace("conn %p created", pConn);
|
||||
++pConn->ref;
|
||||
|
@ -610,7 +642,7 @@ static void destroyConn(SSrvConn* conn, bool clear) {
|
|||
if (conn == NULL) {
|
||||
return;
|
||||
}
|
||||
tTrace("server conn %p try to destroy", conn);
|
||||
tTrace("server conn %p try to destroy, ref: %d", conn, conn->ref);
|
||||
if (--conn->ref > 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -621,19 +653,18 @@ static void destroyConn(SSrvConn* conn, bool clear) {
|
|||
destroySmsg(msg);
|
||||
}
|
||||
taosArrayDestroy(conn->srvMsgs);
|
||||
|
||||
// destroySmsg(conn->pSrvMsg);
|
||||
// conn->pSrvMsg = NULL;
|
||||
QUEUE_REMOVE(&conn->queue);
|
||||
|
||||
if (clear) {
|
||||
uv_close((uv_handle_t*)conn->pTcp, uvDestroyConn);
|
||||
uv_tcp_close_reset(conn->pTcp, uvDestroyConn);
|
||||
// uv_close((uv_handle_t*)conn->pTcp, uvDestroyConn);
|
||||
}
|
||||
}
|
||||
static void uvDestroyConn(uv_handle_t* handle) {
|
||||
SSrvConn* conn = handle->data;
|
||||
tDebug("server conn %p destroy", conn);
|
||||
uv_timer_stop(conn->pTimer);
|
||||
free(conn->pTimer);
|
||||
// free(conn->pTimer);
|
||||
// free(conn->pTcp);
|
||||
free(conn->pWriter);
|
||||
free(conn);
|
||||
|
|
|
@ -22,11 +22,10 @@
|
|||
* windows implementation
|
||||
*/
|
||||
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Mmsystem.h>
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#pragma warning(disable : 4244)
|
||||
|
||||
|
@ -50,9 +49,7 @@ int taosInitTimer(win_timer_f callback, int ms) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void taosUninitTimer() {
|
||||
timeKillEvent(timerId);
|
||||
}
|
||||
void taosUninitTimer() { timeKillEvent(timerId); }
|
||||
|
||||
#elif defined(_TD_DARWIN_64)
|
||||
|
||||
|
@ -60,8 +57,8 @@ void taosUninitTimer() {
|
|||
* darwin implementation
|
||||
*/
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void (*timer_callback)(int);
|
||||
|
@ -93,6 +90,8 @@ static void* timer_routine(void *arg) {
|
|||
|
||||
int taosInitTimer(void (*callback)(int), int ms) {
|
||||
int r = 0;
|
||||
timer_kq = -1;
|
||||
timer_stop = 0;
|
||||
timer_ms = ms;
|
||||
timer_callback = callback;
|
||||
|
||||
|
@ -203,6 +202,7 @@ static void *taosProcessAlarmSignal(void *tharg) {
|
|||
}
|
||||
|
||||
int taosInitTimer(void (*callback)(int), int ms) {
|
||||
stopTimer = false;
|
||||
pthread_attr_t tattr;
|
||||
pthread_attr_init(&tattr);
|
||||
int code = pthread_create(&timerThread, &tattr, taosProcessAlarmSignal, callback);
|
||||
|
|
|
@ -13,19 +13,49 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ttimer.h"
|
||||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
#include "tlog.h"
|
||||
#include "tsched.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
#include "taoserror.h"
|
||||
|
||||
#define tmrFatal(...) { if (tmrDebugFlag & DEBUG_FATAL) { taosPrintLog("TMR FATAL ", tmrDebugFlag, __VA_ARGS__); }}
|
||||
#define tmrError(...) { if (tmrDebugFlag & DEBUG_ERROR) { taosPrintLog("TMR ERROR ", tmrDebugFlag, __VA_ARGS__); }}
|
||||
#define tmrWarn(...) { if (tmrDebugFlag & DEBUG_WARN) { taosPrintLog("TMR WARN ", tmrDebugFlag, __VA_ARGS__); }}
|
||||
#define tmrInfo(...) { if (tmrDebugFlag & DEBUG_INFO) { taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); }}
|
||||
#define tmrDebug(...) { if (tmrDebugFlag & DEBUG_DEBUG) { taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); }}
|
||||
#define tmrTrace(...) { if (tmrDebugFlag & DEBUG_TRACE) { taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); }}
|
||||
#define tmrFatal(...) \
|
||||
{ \
|
||||
if (tmrDebugFlag & DEBUG_FATAL) { \
|
||||
taosPrintLog("TMR FATAL ", tmrDebugFlag, __VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
#define tmrError(...) \
|
||||
{ \
|
||||
if (tmrDebugFlag & DEBUG_ERROR) { \
|
||||
taosPrintLog("TMR ERROR ", tmrDebugFlag, __VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
#define tmrWarn(...) \
|
||||
{ \
|
||||
if (tmrDebugFlag & DEBUG_WARN) { \
|
||||
taosPrintLog("TMR WARN ", tmrDebugFlag, __VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
#define tmrInfo(...) \
|
||||
{ \
|
||||
if (tmrDebugFlag & DEBUG_INFO) { \
|
||||
taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
#define tmrDebug(...) \
|
||||
{ \
|
||||
if (tmrDebugFlag & DEBUG_DEBUG) { \
|
||||
taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
#define tmrTrace(...) \
|
||||
{ \
|
||||
if (tmrDebugFlag & DEBUG_TRACE) { \
|
||||
taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define TIMER_STATE_WAITING 0
|
||||
#define TIMER_STATE_EXPIRED 1
|
||||
|
@ -491,6 +521,8 @@ static void taosTmrModuleInit(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
memset(&timerMap, 0, sizeof(timerMap));
|
||||
|
||||
for (uint32_t i = 0; i < tsMaxTmrCtrl - 1; ++i) {
|
||||
tmr_ctrl_t* ctrl = tmrCtrls + i;
|
||||
ctrl->next = ctrl + 1;
|
||||
|
@ -570,6 +602,7 @@ void taosTmrCleanUp(void* handle) {
|
|||
unusedTmrCtrl = ctrl;
|
||||
pthread_mutex_unlock(&tmrCtrlMutex);
|
||||
|
||||
tmrDebug("time controller's tmr ctrl size: %d", numOfTmrCtrl);
|
||||
if (numOfTmrCtrl <= 0) {
|
||||
taosUninitTimer();
|
||||
|
||||
|
@ -595,6 +628,8 @@ void taosTmrCleanUp(void* handle) {
|
|||
free(timerMap.slots);
|
||||
free(tmrCtrls);
|
||||
|
||||
tmrDebug("timer module is cleaned up");
|
||||
tmrCtrls = NULL;
|
||||
unusedTmrCtrl = NULL;
|
||||
tmrModuleInit = PTHREAD_ONCE_INIT; // to support restart
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue