fix: udfd pipe can close before sending response
This commit is contained in:
parent
cf6508c756
commit
190fbe849e
|
@ -28,7 +28,7 @@
|
|||
#include "tmsg.h"
|
||||
#include "trpc.h"
|
||||
#include "tmisce.h"
|
||||
// clang-foramt on
|
||||
// clang-format on
|
||||
|
||||
typedef struct SUdfdContext {
|
||||
uv_loop_t *loop;
|
||||
|
@ -49,18 +49,25 @@ typedef struct SUdfdContext {
|
|||
|
||||
SUdfdContext global;
|
||||
|
||||
struct SUdfdUvConn;
|
||||
struct SUvUdfWork;
|
||||
|
||||
typedef struct SUdfdUvConn {
|
||||
uv_stream_t *client;
|
||||
char *inputBuf;
|
||||
int32_t inputLen;
|
||||
int32_t inputCap;
|
||||
int32_t inputTotal;
|
||||
|
||||
struct SUvUdfWork *pWorkList; // head of work list
|
||||
} SUdfdUvConn;
|
||||
|
||||
typedef struct SUvUdfWork {
|
||||
uv_stream_t *client;
|
||||
SUdfdUvConn *conn;
|
||||
uv_buf_t input;
|
||||
uv_buf_t output;
|
||||
|
||||
struct SUvUdfWork *pWorkNext;
|
||||
} SUvUdfWork;
|
||||
|
||||
typedef enum { UDF_STATE_INIT = 0, UDF_STATE_LOADING, UDF_STATE_READY, UDF_STATE_UNLOADING } EUdfState;
|
||||
|
@ -248,7 +255,8 @@ void udfdProcessSetupRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
|
|||
|
||||
void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
|
||||
SUdfCallRequest *call = &request->call;
|
||||
fnDebug("call request. call type %d, handle: %" PRIx64 ", seq num %" PRId64 , call->callType, call->udfHandle, request->seqNum);
|
||||
fnDebug("call request. call type %d, handle: %" PRIx64 ", seq num %" PRId64, call->callType, call->udfHandle,
|
||||
request->seqNum);
|
||||
SUdfcFuncHandle *handle = (SUdfcFuncHandle *)(call->udfHandle);
|
||||
SUdf *udf = handle->udf;
|
||||
SUdfResponse response = {0};
|
||||
|
@ -417,7 +425,6 @@ void udfdProcessRpcRsp(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
goto _return;
|
||||
}
|
||||
|
||||
|
||||
if (connectRsp.epSet.numOfEps == 0) {
|
||||
msgInfo->code = TSDB_CODE_APP_ERROR;
|
||||
goto _return;
|
||||
|
@ -601,7 +608,8 @@ static bool udfdRpcRfp(int32_t code, tmsg_t msgType) {
|
|||
if (code == TSDB_CODE_RPC_NETWORK_UNAVAIL || code == TSDB_CODE_RPC_BROKEN_LINK || code == TSDB_CODE_SYN_NOT_LEADER ||
|
||||
code == TSDB_CODE_SYN_RESTORING || code == TSDB_CODE_MNODE_NOT_FOUND || code == TSDB_CODE_APP_IS_STARTING ||
|
||||
code == TSDB_CODE_APP_IS_STOPPING) {
|
||||
if (msgType == TDMT_SCH_QUERY || msgType == TDMT_SCH_MERGE_QUERY || msgType == TDMT_SCH_FETCH || msgType == TDMT_SCH_MERGE_FETCH) {
|
||||
if (msgType == TDMT_SCH_QUERY || msgType == TDMT_SCH_MERGE_QUERY || msgType == TDMT_SCH_FETCH ||
|
||||
msgType == TDMT_SCH_MERGE_FETCH) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -684,6 +692,17 @@ void udfdOnWrite(uv_write_t *req, int status) {
|
|||
if (status < 0) {
|
||||
fnError("udfd send response error, length: %zu code: %s", work->output.len, uv_err_name(status));
|
||||
}
|
||||
// remove work from the connection work list
|
||||
if (work->conn != NULL) {
|
||||
SUvUdfWork **ppWork;
|
||||
for (ppWork = &work->conn->pWorkList; *ppWork && (*ppWork != work); ppWork = &((*ppWork)->pWorkNext)) {
|
||||
}
|
||||
if (*ppWork == work) {
|
||||
*ppWork = work->pWorkNext;
|
||||
} else {
|
||||
fnError("work not in conn any more");
|
||||
}
|
||||
}
|
||||
taosMemoryFree(work->output.base);
|
||||
taosMemoryFree(work);
|
||||
taosMemoryFree(req);
|
||||
|
@ -692,10 +711,11 @@ void udfdOnWrite(uv_write_t *req, int status) {
|
|||
void udfdSendResponse(uv_work_t *work, int status) {
|
||||
SUvUdfWork *udfWork = (SUvUdfWork *)(work->data);
|
||||
|
||||
if (udfWork->conn != NULL) {
|
||||
uv_write_t *write_req = taosMemoryMalloc(sizeof(uv_write_t));
|
||||
write_req->data = udfWork;
|
||||
uv_write(write_req, udfWork->client, &udfWork->output, 1, udfdOnWrite);
|
||||
|
||||
uv_write(write_req, udfWork->conn->client, &udfWork->output, 1, udfdOnWrite);
|
||||
}
|
||||
taosMemoryFree(work);
|
||||
}
|
||||
|
||||
|
@ -751,7 +771,9 @@ void udfdHandleRequest(SUdfdUvConn *conn) {
|
|||
|
||||
uv_work_t *work = taosMemoryMalloc(sizeof(uv_work_t));
|
||||
SUvUdfWork *udfWork = taosMemoryMalloc(sizeof(SUvUdfWork));
|
||||
udfWork->client = conn->client;
|
||||
udfWork->conn = conn;
|
||||
udfWork->pWorkNext = conn->pWorkList;
|
||||
conn->pWorkList = udfWork;
|
||||
udfWork->input = uv_buf_init(inputBuf, inputLen);
|
||||
conn->inputBuf = NULL;
|
||||
conn->inputLen = 0;
|
||||
|
@ -763,6 +785,12 @@ void udfdHandleRequest(SUdfdUvConn *conn) {
|
|||
|
||||
void udfdPipeCloseCb(uv_handle_t *pipe) {
|
||||
SUdfdUvConn *conn = pipe->data;
|
||||
SUvUdfWork* pWork = conn->pWorkList;
|
||||
while (pWork != NULL) {
|
||||
pWork->conn = NULL;
|
||||
pWork = pWork->pWorkNext;
|
||||
}
|
||||
|
||||
taosMemoryFree(conn->client);
|
||||
taosMemoryFree(conn->inputBuf);
|
||||
taosMemoryFree(conn);
|
||||
|
@ -804,6 +832,7 @@ void udfdOnNewConnection(uv_stream_t *server, int status) {
|
|||
uv_pipe_init(global.loop, client, 0);
|
||||
if (uv_accept(server, (uv_stream_t *)client) == 0) {
|
||||
SUdfdUvConn *ctx = taosMemoryMalloc(sizeof(SUdfdUvConn));
|
||||
ctx->pWorkList = NULL;
|
||||
ctx->client = (uv_stream_t *)client;
|
||||
ctx->inputBuf = 0;
|
||||
ctx->inputLen = 0;
|
||||
|
|
Loading…
Reference in New Issue