fix: fix request freed issue

This commit is contained in:
dapan1121 2022-06-29 17:00:48 +08:00
parent 16c6427e7b
commit 4c82ce1810
6 changed files with 78 additions and 112 deletions

View File

@ -69,18 +69,20 @@ typedef struct SSchdFetchParam {
int32_t* code; int32_t* code;
} SSchdFetchParam; } SSchdFetchParam;
typedef void (*schedulerExecCallback)(SQueryResult* pResult, void* param, int32_t code); typedef void (*schedulerExecFp)(SQueryResult* pResult, void* param, int32_t code);
typedef void (*schedulerFetchCallback)(void* pResult, void* param, int32_t code); typedef void (*schedulerFetchFp)(void* pResult, void* param, int32_t code);
typedef bool (*schedulerChkKillFp)(void* param);
typedef struct SSchedulerReq { typedef struct SSchedulerReq {
bool *reqKilled;
SRequestConnInfo *pConn; SRequestConnInfo *pConn;
SArray *pNodeList; SArray *pNodeList;
SQueryPlan *pDag; SQueryPlan *pDag;
const char *sql; const char *sql;
int64_t startTs; int64_t startTs;
schedulerExecCallback fp; schedulerExecFp execFp;
void* cbParam; void* execParam;
schedulerChkKillFp chkKillFp;
void* chkKillParam;
} SSchedulerReq; } SSchedulerReq;
@ -110,7 +112,7 @@ int32_t schedulerExecJob(SSchedulerReq *pReq, int64_t *pJob, SQueryResult *pRes)
*/ */
int32_t schedulerFetchRows(int64_t job, void **data); int32_t schedulerFetchRows(int64_t job, void **data);
void schedulerAsyncFetchRows(int64_t job, schedulerFetchCallback fp, void* param); void schedulerAsyncFetchRows(int64_t job, schedulerFetchFp fp, void* param);
int32_t schedulerGetTasksStatus(int64_t job, SArray *pSub); int32_t schedulerGetTasksStatus(int64_t job, SArray *pSub);

View File

@ -55,6 +55,18 @@ static char* getClusterKey(const char* user, const char* auth, const char* ip, i
return strdup(key); return strdup(key);
} }
bool chkRequestKilled(void* param) {
bool killed = false;
SRequestObj* pRequest = acquireRequest((int64_t)param);
if (NULL == pRequest || pRequest->killed) {
killed = true;
}
releaseRequest((int64_t)param);
return killed;
}
static STscObj* taosConnectImpl(const char* user, const char* auth, const char* db, __taos_async_fn_t fp, void* param, static STscObj* taosConnectImpl(const char* user, const char* auth, const char* db, __taos_async_fn_t fp, void* param,
SAppInstInfo* pAppInfo, int connType); SAppInstInfo* pAppInfo, int connType);
@ -612,58 +624,6 @@ _return:
return code; return code;
} }
int32_t scheduleAsyncQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
tsem_init(&schdRspSem, 0, 0);
SQueryResult res = {.code = 0, .numOfRows = 0};
SRequestConnInfo conn = {.pTrans = pRequest->pTscObj->pAppInfo->pTransporter,
.requestId = pRequest->requestId,
.requestObjRefId = pRequest->self};
SSchedulerReq req = {.pConn = &conn,
.pNodeList = pNodeList,
.pDag = pDag,
.sql = pRequest->sqlstr,
.startTs = pRequest->metric.start,
.fp = schdExecCallback,
.cbParam = &res};
int32_t code = schedulerAsyncExecJob(&req, &pRequest->body.queryJob);
pRequest->body.resInfo.execRes = res.res;
while (true) {
if (code != TSDB_CODE_SUCCESS) {
if (pRequest->body.queryJob != 0) {
schedulerFreeJob(pRequest->body.queryJob, 0);
}
pRequest->code = code;
terrno = code;
return pRequest->code;
} else {
tsem_wait(&schdRspSem);
if (res.code) {
code = res.code;
} else {
break;
}
}
}
if (TDMT_VND_SUBMIT == pRequest->type || TDMT_VND_CREATE_TABLE == pRequest->type) {
pRequest->body.resInfo.numOfRows = res.numOfRows;
if (pRequest->body.queryJob != 0) {
schedulerFreeJob(pRequest->body.queryJob, 0);
}
}
pRequest->code = res.code;
terrno = res.code;
return pRequest->code;
}
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) { int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter; void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
@ -676,9 +636,10 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList
.pDag = pDag, .pDag = pDag,
.sql = pRequest->sqlstr, .sql = pRequest->sqlstr,
.startTs = pRequest->metric.start, .startTs = pRequest->metric.start,
.fp = NULL, .execFp = NULL,
.cbParam = NULL, .execParam = NULL,
.reqKilled = &pRequest->killed}; .chkKillFp = chkRequestKilled,
.chkKillParam = (void*)pRequest->self};
int32_t code = schedulerExecJob(&req, &pRequest->body.queryJob, &res); int32_t code = schedulerExecJob(&req, &pRequest->body.queryJob, &res);
pRequest->body.resInfo.execRes = res.res; pRequest->body.resInfo.execRes = res.res;
@ -986,9 +947,10 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultM
.pDag = pDag, .pDag = pDag,
.sql = pRequest->sqlstr, .sql = pRequest->sqlstr,
.startTs = pRequest->metric.start, .startTs = pRequest->metric.start,
.fp = schedulerExecCb, .execFp = schedulerExecCb,
.cbParam = pRequest, .execParam = pRequest,
.reqKilled = &pRequest->killed}; .chkKillFp = chkRequestKilled,
.chkKillParam = (void*)pRequest->self};
code = schedulerAsyncExecJob(&req, &pRequest->body.queryJob); code = schedulerAsyncExecJob(&req, &pRequest->body.queryJob);
taosArrayDestroy(pNodeList); taosArrayDestroy(pNodeList);
} else { } else {

View File

@ -99,8 +99,8 @@ typedef struct SSchStat {
typedef struct SSchResInfo { typedef struct SSchResInfo {
SQueryResult* queryRes; SQueryResult* queryRes;
void** fetchRes; void** fetchRes;
schedulerExecCallback execFp; schedulerExecFp execFp;
schedulerFetchCallback fetchFp; schedulerFetchFp fetchFp;
void* userParam; void* userParam;
} SSchResInfo; } SSchResInfo;
@ -204,37 +204,38 @@ typedef struct {
} SSchOpStatus; } SSchOpStatus;
typedef struct SSchJob { typedef struct SSchJob {
int64_t refId; int64_t refId;
uint64_t queryId; uint64_t queryId;
SSchJobAttr attr; SSchJobAttr attr;
int32_t levelNum; int32_t levelNum;
int32_t taskNum; int32_t taskNum;
SRequestConnInfo conn; SRequestConnInfo conn;
SArray *nodeList; // qnode/vnode list, SArray<SQueryNodeLoad> SArray *nodeList; // qnode/vnode list, SArray<SQueryNodeLoad>
SArray *levels; // starting from 0. SArray<SSchLevel> SArray *levels; // starting from 0. SArray<SSchLevel>
SQueryPlan *pDag; SQueryPlan *pDag;
SArray *dataSrcTasks; // SArray<SQueryTask*> SArray *dataSrcTasks; // SArray<SQueryTask*>
int32_t levelIdx; int32_t levelIdx;
SEpSet dataSrcEps; SEpSet dataSrcEps;
SHashObj *taskList; SHashObj *taskList;
SHashObj *execTasks; // executing and executed tasks, key:taskid, value:SQueryTask* SHashObj *execTasks; // executing and executed tasks, key:taskid, value:SQueryTask*
SHashObj *flowCtrl; // key is ep, element is SSchFlowControl SHashObj *flowCtrl; // key is ep, element is SSchFlowControl
SExplainCtx *explainCtx; SExplainCtx *explainCtx;
int8_t status; int8_t status;
SQueryNodeAddr resNode; SQueryNodeAddr resNode;
tsem_t rspSem; tsem_t rspSem;
SSchOpStatus opStatus; SSchOpStatus opStatus;
bool *reqKilled; schedulerChkKillFp chkKillFp;
SSchTask *fetchTask; void* chkKillParam;
int32_t errCode; SSchTask *fetchTask;
SRWLatch resLock; int32_t errCode;
SQueryExecRes execRes; SRWLatch resLock;
void *resData; //TODO free it or not SQueryExecRes execRes;
int32_t resNumOfRows; void *resData; //TODO free it or not
SSchResInfo userRes; int32_t resNumOfRows;
const char *sql; SSchResInfo userRes;
const char *sql;
SQueryProfileSummary summary; SQueryProfileSummary summary;
} SSchJob; } SSchJob;

View File

@ -55,9 +55,10 @@ int32_t schInitJob(SSchedulerReq *pReq, SSchJob **pSchJob) {
pJob->conn = *pReq->pConn; pJob->conn = *pReq->pConn;
pJob->sql = pReq->sql; pJob->sql = pReq->sql;
pJob->pDag = pReq->pDag; pJob->pDag = pReq->pDag;
pJob->reqKilled = pReq->reqKilled; pJob->chkKillFp = pReq->chkKillFp;
pJob->userRes.execFp = pReq->fp; pJob->chkKillParam = pReq->chkKillParam;
pJob->userRes.userParam = pReq->cbParam; pJob->userRes.execFp = pReq->execFp;
pJob->userRes.userParam = pReq->execParam;
if (pReq->pNodeList == NULL || taosArrayGetSize(pReq->pNodeList) <= 0) { if (pReq->pNodeList == NULL || taosArrayGetSize(pReq->pNodeList) <= 0) {
qDebug("QID:0x%" PRIx64 " input exec nodeList is empty", pReq->pDag->queryId); qDebug("QID:0x%" PRIx64 " input exec nodeList is empty", pReq->pDag->queryId);
@ -182,7 +183,7 @@ FORCE_INLINE bool schJobNeedToStop(SSchJob *pJob, int8_t *pStatus) {
*pStatus = status; *pStatus = status;
} }
if (*pJob->reqKilled) { if ((*pJob->chkKillFp)(pJob->chkKillParam)) {
schUpdateJobStatus(pJob, JOB_TASK_STATUS_DROPPING); schUpdateJobStatus(pJob, JOB_TASK_STATUS_DROPPING);
schUpdateJobErrCode(pJob, TSDB_CODE_TSC_QUERY_KILLED); schUpdateJobErrCode(pJob, TSDB_CODE_TSC_QUERY_KILLED);
@ -1584,7 +1585,7 @@ _return:
schEndOperation(pJob); schEndOperation(pJob);
if (!sync) { if (!sync) {
pReq->fp(NULL, pReq->cbParam, code); pReq->execFp(NULL, pReq->execParam, code);
} }
schFreeJobImpl(pJob); schFreeJobImpl(pJob);
@ -1651,7 +1652,7 @@ int32_t schExecJobImpl(SSchedulerReq *pReq, SSchJob *pJob, bool sync) {
_return: _return:
if (!sync) { if (!sync) {
pReq->fp(NULL, pReq->cbParam, code); pReq->execFp(NULL, pReq->execParam, code);
} }
SCH_RET(code); SCH_RET(code);

View File

@ -140,7 +140,7 @@ int32_t schedulerFetchRows(int64_t job, void **pData) {
SCH_RET(code); SCH_RET(code);
} }
void schedulerAsyncFetchRows(int64_t job, schedulerFetchCallback fp, void* param) { void schedulerAsyncFetchRows(int64_t job, schedulerFetchFp fp, void* param) {
qDebug("scheduler async fetch rows start"); qDebug("scheduler async fetch rows start");
int32_t code = 0; int32_t code = 0;

View File

@ -511,8 +511,8 @@ void* schtRunJobThread(void *aa) {
req.pNodeList = qnodeList; req.pNodeList = qnodeList;
req.pDag = &dag; req.pDag = &dag;
req.sql = "select * from tb"; req.sql = "select * from tb";
req.fp = schtQueryCb; req.execFp = schtQueryCb;
req.cbParam = &queryDone; req.execParam = &queryDone;
code = schedulerAsyncExecJob(&req, &queryJobRefId); code = schedulerAsyncExecJob(&req, &queryJobRefId);
assert(code == 0); assert(code == 0);
@ -663,8 +663,8 @@ TEST(queryTest, normalCase) {
req.pNodeList = qnodeList; req.pNodeList = qnodeList;
req.pDag = &dag; req.pDag = &dag;
req.sql = "select * from tb"; req.sql = "select * from tb";
req.fp = schtQueryCb; req.execFp = schtQueryCb;
req.cbParam = &queryDone; req.execParam = &queryDone;
code = schedulerAsyncExecJob(&req, &job); code = schedulerAsyncExecJob(&req, &job);
ASSERT_EQ(code, 0); ASSERT_EQ(code, 0);
@ -767,8 +767,8 @@ TEST(queryTest, readyFirstCase) {
req.pNodeList = qnodeList; req.pNodeList = qnodeList;
req.pDag = &dag; req.pDag = &dag;
req.sql = "select * from tb"; req.sql = "select * from tb";
req.fp = schtQueryCb; req.execFp = schtQueryCb;
req.cbParam = &queryDone; req.execParam = &queryDone;
code = schedulerAsyncExecJob(&req, &job); code = schedulerAsyncExecJob(&req, &job);
ASSERT_EQ(code, 0); ASSERT_EQ(code, 0);
@ -874,8 +874,8 @@ TEST(queryTest, flowCtrlCase) {
req.pNodeList = qnodeList; req.pNodeList = qnodeList;
req.pDag = &dag; req.pDag = &dag;
req.sql = "select * from tb"; req.sql = "select * from tb";
req.fp = schtQueryCb; req.execFp = schtQueryCb;
req.cbParam = &queryDone; req.execParam = &queryDone;
code = schedulerAsyncExecJob(&req, &job); code = schedulerAsyncExecJob(&req, &job);
ASSERT_EQ(code, 0); ASSERT_EQ(code, 0);
@ -987,8 +987,8 @@ TEST(insertTest, normalCase) {
req.pNodeList = qnodeList; req.pNodeList = qnodeList;
req.pDag = &dag; req.pDag = &dag;
req.sql = "insert into tb values(now,1)"; req.sql = "insert into tb values(now,1)";
req.fp = schtQueryCb; req.execFp = schtQueryCb;
req.cbParam = NULL; req.execParam = NULL;
code = schedulerExecJob(&req, &insertJobRefId, &res); code = schedulerExecJob(&req, &insertJobRefId, &res);
ASSERT_EQ(code, 0); ASSERT_EQ(code, 0);