• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3774

28 Mar 2025 06:51AM UTC coverage: 62.934% (+2.6%) from 60.312%
#3774

push

travis-ci

web-flow
fix(tdb): disable page recycling (#30529)

154142 of 313582 branches covered (49.16%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

2163 existing lines in 136 files now uncovered.

240434 of 313390 relevant lines covered (76.72%)

17901958.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.82
/source/dnode/vnode/src/tqCommon/tqCommon.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#include "tmsgcb.h"
17
#include "tq.h"
18
#include "tstream.h"
19

20
typedef struct SMStreamCheckpointReadyRspMsg {
21
  SMsgHead head;
22
  int64_t  streamId;
23
  int32_t  upstreamTaskId;
24
  int32_t  upstreamNodeId;
25
  int32_t  downstreamTaskId;
26
  int32_t  downstreamNodeId;
27
  int64_t  checkpointId;
28
  int32_t  transId;
29
} SMStreamCheckpointReadyRspMsg;
30

31
static int32_t doProcessDummyRspMsg(SStreamMeta* pMeta, SRpcMsg* pMsg);
32

33
int32_t tqExpandStreamTask(SStreamTask* pTask) {
14,384✔
34
  SStreamMeta* pMeta = pTask->pMeta;
14,384✔
35
  int32_t      vgId = pMeta->vgId;
14,384✔
36
  int64_t      st = taosGetTimestampMs();
14,385✔
37
  int64_t      streamId = 0;
14,385✔
38
  int32_t      taskId = 0;
14,385✔
39
  int32_t      code = 0;
14,385✔
40

41
  tqDebug("s-task:%s vgId:%d start to expand stream task", pTask->id.idStr, vgId);
14,385✔
42

43
  if (pTask->info.fillHistory != STREAM_NORMAL_TASK) {
14,385✔
44
    streamId = pTask->streamTaskId.streamId;
4,887✔
45
    taskId = pTask->streamTaskId.taskId;
4,887✔
46
  } else {
47
    streamId = pTask->id.streamId;
9,498✔
48
    taskId = pTask->id.taskId;
9,498✔
49
  }
50

51
  // sink task does not need the pState
52
  if (pTask->info.taskLevel != TASK_LEVEL__SINK) {
14,385✔
53
    if (pTask->info.fillHistory == STREAM_RECALCUL_TASK) {
7,522✔
54
      pTask->pRecalState = streamStateRecalatedOpen(pMeta->path, pTask, pTask->id.streamId, pTask->id.taskId);
36✔
55
      if (pTask->pRecalState == NULL) {
36!
56
        tqError("s-task:%s (vgId:%d) failed to open state for task, expand task failed", pTask->id.idStr, vgId);
×
57
        return terrno;
×
58
      } else {
59
        tqDebug("s-task:%s recal state:%p", pTask->id.idStr, pTask->pRecalState);
36!
60
      }
61
    }
62

63
    pTask->pState = streamStateOpen(pMeta->path, pTask, streamId, taskId);
7,522✔
64
    if (pTask->pState == NULL) {
7,525!
65
      tqError("s-task:%s (vgId:%d) failed to open state for task, expand task failed", pTask->id.idStr, vgId);
×
66
      return terrno;
×
67
    } else {
68
      tqDebug("s-task:%s stream state:%p", pTask->id.idStr, pTask->pState);
7,525✔
69
    }
70
  }
71

72
  SReadHandle handle = {
14,388✔
73
      .checkpointId = pTask->chkInfo.checkpointId,
14,388✔
74
      .pStateBackend = NULL,
75
      .fillHistory = pTask->info.fillHistory,
14,388✔
76
      .winRange = pTask->dataRange.window,
77
      .pOtherBackend = NULL,
78
  };
79

80
  if (pTask->info.taskLevel == TASK_LEVEL__SOURCE || pTask->info.taskLevel == TASK_LEVEL__MERGE) {
14,388!
81
    handle.vnode = ((STQ*)pMeta->ahandle)->pVnode;
7,229✔
82
    handle.initTqReader = 1;
7,229✔
83
  } else if (pTask->info.taskLevel == TASK_LEVEL__AGG) {
7,159✔
84
    handle.numOfVgroups = (int32_t)taosArrayGetSize(pTask->upstreamInfo.pList);
296✔
85
  }
86

87
  initStorageAPI(&handle.api);
14,388✔
88

89
  if (pTask->info.taskLevel == TASK_LEVEL__SOURCE || pTask->info.taskLevel == TASK_LEVEL__AGG ||
14,387✔
90
      pTask->info.taskLevel == TASK_LEVEL__MERGE) {
6,863!
91
    if (pTask->info.fillHistory == STREAM_RECALCUL_TASK) {
7,524✔
92
      handle.pStateBackend = pTask->pRecalState;
36✔
93
      handle.pOtherBackend = pTask->pState;
36✔
94
    } else {
95
      handle.pStateBackend = pTask->pState;
7,488✔
96
      handle.pOtherBackend = NULL;
7,488✔
97
    }
98

99
    code = qCreateStreamExecTaskInfo(&pTask->exec.pExecutor, pTask->exec.qmsg, &handle, vgId, pTask->id.taskId);
7,524✔
100
    if (code) {
7,523!
101
      tqError("s-task:%s failed to expand task, code:%s", pTask->id.idStr, tstrerror(code));
×
102
      return code;
×
103
    }
104

105
    code = qSetTaskId(pTask->exec.pExecutor, pTask->id.taskId, pTask->id.streamId);
7,523✔
106
    if (code) {
7,524!
107
      return code;
×
108
    }
109

110
    code = qSetStreamNotifyInfo(pTask->exec.pExecutor, pTask->notifyInfo.notifyEventTypes,
15,048✔
111
                                pTask->notifyInfo.pSchemaWrapper, pTask->notifyInfo.stbFullName,
7,524✔
112
                                IS_NEW_SUBTB_RULE(pTask), &pTask->notifyEventStat);
7,524✔
113
    if (code) {
7,523!
114
      tqError("s-task:%s failed to set stream notify info, code:%s", pTask->id.idStr, tstrerror(code));
×
115
      return code;
×
116
    }
117

118
    qSetStreamMergeInfo(pTask->exec.pExecutor, pTask->pVTables);
7,523✔
119
  }
120

121
  streamSetupScheduleTrigger(pTask);
14,386✔
122

123
  double el = (taosGetTimestampMs() - st) / 1000.0;
14,387✔
124
  tqDebug("s-task:%s vgId:%d expand stream task completed, elapsed time:%.2fsec", pTask->id.idStr, vgId, el);
14,387✔
125

126
  return code;
14,387✔
127
}
128

129
void tqSetRestoreVersionInfo(SStreamTask* pTask) {
14,740✔
130
  SCheckpointInfo* pChkInfo = &pTask->chkInfo;
14,740✔
131

132
  // checkpoint ver is the kept version, handled data should be the next version.
133
  if (pChkInfo->checkpointId != 0) {
14,740✔
134
    pChkInfo->nextProcessVer = pChkInfo->checkpointVer + 1;
264✔
135
    pChkInfo->processedVer = pChkInfo->checkpointVer;
264✔
136
    pTask->execInfo.startCheckpointId = pChkInfo->checkpointId;
264✔
137

138
    tqInfo("s-task:%s restore from the checkpointId:%" PRId64 " ver:%" PRId64 " currentVer:%" PRId64, pTask->id.idStr,
264!
139
           pChkInfo->checkpointId, pChkInfo->checkpointVer, pChkInfo->nextProcessVer);
140
  }
141

142
  pTask->execInfo.startCheckpointVer = pChkInfo->nextProcessVer;
14,740✔
143
}
14,740✔
144

145
int32_t tqStreamTaskStartAsync(SStreamMeta* pMeta, SMsgCb* cb, bool restart) {
14✔
146
  int32_t vgId = pMeta->vgId;
14✔
147
  int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
14✔
148
  if (numOfTasks == 0) {
14!
149
    tqDebug("vgId:%d no stream tasks existed to run", vgId);
×
150
    return 0;
×
151
  }
152

153
  tqDebug("vgId:%d start all %d stream task(s) async", vgId, numOfTasks);
14!
154

155
  int32_t type = restart ? STREAM_EXEC_T_RESTART_ALL_TASKS : STREAM_EXEC_T_START_ALL_TASKS;
14!
156
  return streamTaskSchedTask(cb, vgId, 0, 0, type, false);
14✔
157
}
158

159
int32_t tqStreamStartOneTaskAsync(SStreamMeta* pMeta, SMsgCb* cb, int64_t streamId, int32_t taskId) {
9,459✔
160
  int32_t vgId = pMeta->vgId;
9,459✔
161
  int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
9,459✔
162
  if (numOfTasks == 0) {
9,460!
163
    tqDebug("vgId:%d no stream tasks existed to run", vgId);
×
164
    return 0;
×
165
  }
166

167
  tqDebug("vgId:%d start task:0x%x async", vgId, taskId);
9,460✔
168
  return streamTaskSchedTask(cb, vgId, streamId, taskId, STREAM_EXEC_T_START_ONE_TASK, false);
9,460✔
169
}
170

171
// this is to process request from transaction, always return true.
172
int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pMsg, bool restored, bool isLeader) {
37✔
173
  int32_t                  vgId = pMeta->vgId;
37✔
174
  char*                    msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
37✔
175
  int32_t                  len = pMsg->contLen - sizeof(SMsgHead);
37✔
176
  SRpcMsg                  rsp = {.info = pMsg->info, .code = TSDB_CODE_SUCCESS};
37✔
177
  int64_t                  st = taosGetTimestampMs();
37✔
178
  bool                     updated = false;
37✔
179
  int32_t                  code = 0;
37✔
180
  SStreamTask*             pTask = NULL;
37✔
181
  SStreamTask*             pHTask = NULL;
37✔
182
  SStreamTaskNodeUpdateMsg req = {0};
37✔
183
  SDecoder                 decoder;
184

185
  tDecoderInit(&decoder, (uint8_t*)msg, len);
37✔
186
  code = tDecodeStreamTaskUpdateMsg(&decoder, &req);
37✔
187
  tDecoderClear(&decoder);
37✔
188

189
  if (code < 0) {
37!
190
    rsp.code = TSDB_CODE_MSG_DECODE_ERROR;
×
191
    tqError("vgId:%d failed to decode task update msg, code:%s", vgId, tstrerror(rsp.code));
×
192
    tDestroyNodeUpdateMsg(&req);
×
193
    return rsp.code;
×
194
  }
195

196
  int32_t gError = streamGetFatalError(pMeta);
37✔
197
  if (gError != 0) {
37!
198
    tqError("vgId:%d global fatal occurs, code:%s, ts:%" PRId64 " func:%s", pMeta->vgId, tstrerror(gError),
×
199
            pMeta->fatalInfo.ts, pMeta->fatalInfo.func);
200
    return 0;
×
201
  }
202

203
  // update the nodeEpset when it exists
204
  streamMetaWLock(pMeta);
37✔
205

206
  // the task epset may be updated again and again, when replaying the WAL, the task may be in stop status.
207
  STaskId id = {.streamId = req.streamId, .taskId = req.taskId};
37✔
208
  code = streamMetaAcquireTaskUnsafe(pMeta, &id, &pTask);
37✔
209
  if (code != 0) {
37!
210
    tqError("vgId:%d failed to acquire task:0x%x when handling update task epset, it may have been dropped", vgId,
×
211
            req.taskId);
212
    rsp.code = TSDB_CODE_SUCCESS;
×
213
    streamMetaWUnLock(pMeta);
×
214
    taosArrayDestroy(req.pNodeList);
×
215
    return rsp.code;
×
216
  }
217

218
  const char* idstr = pTask->id.idStr;
37✔
219

220
  if (req.transId <= 0) {
37!
221
    tqError("vgId:%d invalid update nodeEp task, transId:%d, discard", vgId, req.taskId);
×
222
    rsp.code = TSDB_CODE_SUCCESS;
×
223

224
    streamMetaReleaseTask(pMeta, pTask);
×
225
    streamMetaWUnLock(pMeta);
×
226

227
    taosArrayDestroy(req.pNodeList);
×
228
    return rsp.code;
×
229
  }
230

231
  // info needs to be kept till the new trans to update the nodeEp arrived.
232
  bool update = streamMetaInitUpdateTaskList(pMeta, req.transId);
37✔
233
  if (!update) {
37!
234
    rsp.code = TSDB_CODE_SUCCESS;
×
235

236
    streamMetaReleaseTask(pMeta, pTask);
×
237
    streamMetaWUnLock(pMeta);
×
238

239
    taosArrayDestroy(req.pNodeList);
×
240
    return rsp.code;
×
241
  }
242

243
  // duplicate update epset msg received, discard this redundant message
244
  STaskUpdateEntry entry = {.streamId = req.streamId, .taskId = req.taskId, .transId = req.transId};
37✔
245

246
  void* pReqTask = taosHashGet(pMeta->updateInfo.pTasks, &entry, sizeof(STaskUpdateEntry));
37✔
247
  if (pReqTask != NULL) {
37!
248
    tqDebug("s-task:%s (vgId:%d) already update in transId:%d, discard the nodeEp update msg", idstr, vgId,
×
249
            req.transId);
250
    rsp.code = TSDB_CODE_SUCCESS;
×
251

252
    streamMetaReleaseTask(pMeta, pTask);
×
253
    streamMetaWUnLock(pMeta);
×
254

255
    taosArrayDestroy(req.pNodeList);
×
256
    return rsp.code;
×
257
  }
258

259
  updated = streamTaskUpdateEpsetInfo(pTask, req.pNodeList);
37✔
260

261
  // send the checkpoint-source-rsp for source task to end the checkpoint trans in mnode
262
  code = streamTaskSendCheckpointsourceRsp(pTask);
37✔
263
  if (code) {
37!
264
    tqError("%s failed to send checkpoint-source rsp, code:%s", pTask->id.idStr, tstrerror(code));
×
265
  }
266
  streamTaskResetStatus(pTask);
37✔
267

268
  streamTaskStopMonitorCheckRsp(&pTask->taskCheckInfo, pTask->id.idStr);
37✔
269

270
  if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
37✔
271
    code = streamMetaAcquireTaskUnsafe(pMeta, &pTask->hTaskInfo.id, &pHTask);
25✔
272
    if (code != 0) {
25!
273
      tqError(
×
274
          "vgId:%d failed to acquire fill-history task:0x%x when handling update, may have been dropped already, rel "
275
          "stream task:0x%x",
276
          vgId, (uint32_t)pTask->hTaskInfo.id.taskId, req.taskId);
277
      CLEAR_RELATED_FILLHISTORY_TASK(pTask);
×
278
    } else {
279
      tqDebug("s-task:%s fill-history task update nodeEp along with stream task", pHTask->id.idStr);
25!
280
      bool updateEpSet = streamTaskUpdateEpsetInfo(pHTask, req.pNodeList);
25✔
281
      if (updateEpSet) {
25!
282
        updated = updateEpSet;
25✔
283
      }
284

285
      streamTaskResetStatus(pHTask);
25✔
286
      streamTaskStopMonitorCheckRsp(&pHTask->taskCheckInfo, pHTask->id.idStr);
25✔
287
    }
288
  }
289

290
  // stream do update the nodeEp info, write it into stream meta.
291
  if (updated) {
37✔
292
    tqDebug("s-task:%s vgId:%d save task after update epset, and stop task", idstr, vgId);
32!
293
    code = streamMetaSaveTaskInMeta(pMeta, pTask);
32✔
294
    if (code) {
32!
295
      tqError("s-task:%s vgId:%d failed to save task, code:%s", idstr, vgId, tstrerror(code));
×
296
    }
297

298
    if (pHTask != NULL) {
32✔
299
      code = streamMetaSaveTaskInMeta(pMeta, pHTask);
25✔
300
      if (code) {
25!
301
        tqError("s-task:%s vgId:%d failed to save related history task, code:%s", idstr, vgId, tstrerror(code));
×
302
      }
303
    }
304
  } else {
305
    tqDebug("s-task:%s vgId:%d not save task since not update epset actually, stop task", idstr, vgId);
5!
306
  }
307

308
  code = streamTaskStop(pTask);
37✔
309
  if (code) {
37!
310
    tqError("s-task:%s vgId:%d failed to stop task, code:%s", idstr, vgId, tstrerror(code));
×
311
  }
312

313
  if (pHTask != NULL) {
37✔
314
    code = streamTaskStop(pHTask);
25✔
315
    if (code) {
25!
316
      tqError("s-task:%s vgId:%d failed to stop related history task, code:%s", idstr, vgId, tstrerror(code));
×
317
    }
318
  }
319

320
  // keep info
321
  streamMetaAddIntoUpdateTaskList(pMeta, pTask, (pHTask != NULL) ? (pHTask) : NULL, req.transId, st);
37✔
322
  streamMetaReleaseTask(pMeta, pTask);
37✔
323
  streamMetaReleaseTask(pMeta, pHTask);
37✔
324

325
  rsp.code = TSDB_CODE_SUCCESS;
37✔
326

327
  // possibly only handle the stream task.
328
  int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta);
37✔
329
  int32_t updateTasks = taosHashGetSize(pMeta->updateInfo.pTasks);
37✔
330

331
  if (restored && isLeader) {
37!
332
    tqDebug("vgId:%d s-task:0x%x update epset transId:%d, set the restart flag", vgId, req.taskId, req.transId);
25!
333
    pMeta->startInfo.tasksWillRestart = 1;
25✔
334
  }
335

336
  if (updateTasks < numOfTasks) {
37✔
337
    if (isLeader) {
17✔
338
      tqDebug("vgId:%d closed tasks:%d, unclosed:%d, all tasks will be started when nodeEp update completed", vgId,
11!
339
              updateTasks, (numOfTasks - updateTasks));
340
    } else {
341
      tqDebug("vgId:%d closed tasks:%d, unclosed:%d, follower not restart tasks", vgId, updateTasks,
6!
342
              (numOfTasks - updateTasks));
343
    }
344
  } else {
345
    if ((code = streamMetaCommit(pMeta)) < 0) {
20!
346
      // always return true
347
      streamMetaWUnLock(pMeta);
×
348
      taosArrayDestroy(req.pNodeList);
×
349
      return TSDB_CODE_SUCCESS;
×
350
    }
351

352
    streamMetaClearSetUpdateTaskListComplete(pMeta);
20✔
353

354
    if (isLeader) {
20✔
355
      if (!restored) {
14!
356
        tqDebug("vgId:%d vnode restore not completed, not start all tasks", vgId);
×
357
      } else {
358
        tqDebug("vgId:%d all %d task(s) nodeEp updated and closed, transId:%d", vgId, numOfTasks, req.transId);
14!
359
#if 0
360
      taosMSleep(5000);// for test purpose, to trigger the leader election
361
#endif
362
        code = tqStreamTaskStartAsync(pMeta, cb, true);
14✔
363
        if (code) {
14!
364
          tqError("vgId:%d async start all tasks, failed, code:%s", vgId, tstrerror(code));
×
365
        }
366
      }
367
    } else {
368
      tqDebug("vgId:%d follower nodes not restart tasks", vgId);
6!
369
    }
370
  }
371

372
  streamMetaWUnLock(pMeta);
37✔
373
  taosArrayDestroy(req.pNodeList);
37✔
374
  return rsp.code;  // always return true
37✔
375
}
376

377
int32_t tqStreamTaskProcessDispatchReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
59,568✔
378
  char*   msgStr = pMsg->pCont;
59,568✔
379
  char*   msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead));
59,568✔
380
  int32_t msgLen = pMsg->contLen - sizeof(SMsgHead);
59,568✔
381

382
  SStreamDispatchReq req = {0};
59,568✔
383

384
  SDecoder decoder;
385
  tDecoderInit(&decoder, (uint8_t*)msgBody, msgLen);
59,568✔
386
  if (tDecodeStreamDispatchReq(&decoder, &req) < 0) {
59,557!
387
    tDecoderClear(&decoder);
×
388
    return TSDB_CODE_MSG_DECODE_ERROR;
×
389
  }
390
  tDecoderClear(&decoder);
59,562✔
391

392
  tqDebug("s-task:0x%x recv dispatch msg from 0x%x(vgId:%d)", req.taskId, req.upstreamTaskId, req.upstreamNodeId);
59,578✔
393

394
  SStreamTask* pTask = NULL;
59,578✔
395
  int32_t      code = streamMetaAcquireTask(pMeta, req.streamId, req.taskId, &pTask);
59,578✔
396
  if (pTask && (code == 0)) {
59,565!
397
    SRpcMsg rsp = {.info = pMsg->info, .code = 0};
59,573✔
398
    if (streamProcessDispatchMsg(pTask, &req, &rsp) != 0) {
59,573!
399
      return -1;
×
400
    }
401
    tCleanupStreamDispatchReq(&req);
59,573✔
402
    streamMetaReleaseTask(pMeta, pTask);
59,580✔
403
    return 0;
59,582✔
404
  } else {
405
    tqError("vgId:%d failed to find task:0x%x to handle the dispatch req, it may have been destroyed already",
×
406
            pMeta->vgId, req.taskId);
407

408
    SMsgHead* pRspHead = rpcMallocCont(sizeof(SMsgHead) + sizeof(SStreamDispatchRsp));
×
409
    if (pRspHead == NULL) {
9!
410
      tqError("s-task:0x%x send dispatch error rsp, out of memory", req.taskId);
×
411
      return terrno;
×
412
    }
413

414
    pRspHead->vgId = htonl(req.upstreamNodeId);
9✔
415
    if (pRspHead->vgId == 0) {
9!
416
      tqError("vgId:%d invalid dispatch msg from upstream to task:0x%x", pMeta->vgId, req.taskId);
×
417
      return TSDB_CODE_INVALID_MSG;
×
418
    }
419

420
    SStreamDispatchRsp* pRsp = POINTER_SHIFT(pRspHead, sizeof(SMsgHead));
9✔
421
    pRsp->streamId = htobe64(req.streamId);
9✔
422
    pRsp->upstreamTaskId = htonl(req.upstreamTaskId);
9✔
423
    pRsp->upstreamNodeId = htonl(req.upstreamNodeId);
9✔
424
    pRsp->downstreamNodeId = htonl(pMeta->vgId);
9✔
425
    pRsp->downstreamTaskId = htonl(req.taskId);
9✔
426
    pRsp->msgId = htonl(req.msgId);
9✔
427
    pRsp->stage = htobe64(req.stage);
9✔
428
    pRsp->inputStatus = TASK_OUTPUT_STATUS__NORMAL;
9✔
429

430
    int32_t len = sizeof(SMsgHead) + sizeof(SStreamDispatchRsp);
9✔
431
    SRpcMsg rsp = {.code = TSDB_CODE_STREAM_TASK_NOT_EXIST, .info = pMsg->info, .contLen = len, .pCont = pRspHead};
9✔
432
    tqError("s-task:0x%x send dispatch error rsp, no task", req.taskId);
9!
433

434
    tmsgSendRsp(&rsp);
9✔
435
    tCleanupStreamDispatchReq(&req);
9✔
436

437
    return 0;
9✔
438
  }
439
}
440

441
int32_t tqStreamTaskProcessDispatchRsp(SStreamMeta* pMeta, SRpcMsg* pMsg) {
59,597✔
442
  SStreamDispatchRsp* pRsp = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
59,597✔
443

444
  int32_t vgId = pMeta->vgId;
59,597✔
445
  pRsp->upstreamNodeId = htonl(pRsp->upstreamNodeId);
59,597✔
446
  pRsp->upstreamTaskId = htonl(pRsp->upstreamTaskId);
59,597✔
447
  pRsp->streamId = htobe64(pRsp->streamId);
59,597✔
448
  pRsp->downstreamTaskId = htonl(pRsp->downstreamTaskId);
59,596✔
449
  pRsp->downstreamNodeId = htonl(pRsp->downstreamNodeId);
59,596✔
450
  pRsp->stage = htobe64(pRsp->stage);
59,596✔
451
  pRsp->msgId = htonl(pRsp->msgId);
59,597✔
452

453
  tqDebug("s-task:0x%x vgId:%d recv dispatch-rsp from 0x%x vgId:%d", pRsp->upstreamTaskId, pRsp->upstreamNodeId,
59,597✔
454
          pRsp->downstreamTaskId, pRsp->downstreamNodeId);
455

456
  SStreamTask* pTask = NULL;
59,597✔
457
  int32_t      code = streamMetaAcquireTask(pMeta, pRsp->streamId, pRsp->upstreamTaskId, &pTask);
59,597✔
458
  if (pTask && (code == 0)) {
59,596!
459
    code = streamProcessDispatchRsp(pTask, pRsp, pMsg->code);
59,591✔
460
    streamMetaReleaseTask(pMeta, pTask);
59,590✔
461
    return code;
59,589✔
462
  } else {
463
    tqDebug("vgId:%d failed to handle the dispatch rsp, since find task:0x%x failed", vgId, pRsp->upstreamTaskId);
5!
464
    return TSDB_CODE_STREAM_TASK_NOT_EXIST;
8✔
465
  }
466
}
467

468
int32_t tqStreamTaskProcessRetrieveReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
540✔
469
  char*    msgStr = pMsg->pCont;
540✔
470
  char*    msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead));
540✔
471
  int32_t  msgLen = pMsg->contLen - sizeof(SMsgHead);
540✔
472
  int32_t  code = 0;
540✔
473
  SDecoder decoder;
474

475
  SStreamRetrieveReq req;
476
  tDecoderInit(&decoder, (uint8_t*)msgBody, msgLen);
540✔
477
  code = tDecodeStreamRetrieveReq(&decoder, &req);
540✔
478
  tDecoderClear(&decoder);
538✔
479

480
  if (code) {
538!
481
    tqError("vgId:%d failed to decode retrieve msg, discard it", pMeta->vgId);
×
482
    return code;
×
483
  }
484

485
  SStreamTask* pTask = NULL;
538✔
486
  code = streamMetaAcquireTask(pMeta, req.streamId, req.dstTaskId, &pTask);
538✔
487
  if (pTask == NULL || code != 0) {
540!
UNCOV
488
    tqError("vgId:%d process retrieve req, failed to acquire task:0x%x, it may have been dropped already", pMeta->vgId,
×
489
            req.dstTaskId);
UNCOV
490
    tCleanupStreamRetrieveReq(&req);
×
491
    return code;
×
492
  }
493

494
  // enqueue
495
  tqDebug("s-task:%s (vgId:%d level:%d) recv retrieve req from task:0x%x(vgId:%d), QID:0x%" PRIx64, pTask->id.idStr,
540✔
496
          pTask->pMeta->vgId, pTask->info.taskLevel, req.srcTaskId, req.srcNodeId, req.reqId);
497

498
  // if task is in ck status, set current ck failed
499
  streamTaskSetCheckpointFailed(pTask);
540✔
500

501
  if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) {
540✔
502
    code = streamProcessRetrieveReq(pTask, &req);
534✔
503
  } else {
504
    req.srcNodeId = pTask->info.nodeId;
6✔
505
    req.srcTaskId = pTask->id.taskId;
6✔
506
    code = streamTaskBroadcastRetrieveReq(pTask, &req);
6✔
507
  }
508

509
  if (code != TSDB_CODE_SUCCESS) {  // return error not send rsp manually
539!
510
    tqError("s-task:0x%x vgId:%d failed to process retrieve request from 0x%x, code:%s", req.dstTaskId, req.dstNodeId,
×
511
            req.srcTaskId, tstrerror(code));
512
  } else {  // send rsp manually only on success.
513
    SRpcMsg rsp = {.info = pMsg->info, .code = 0};
539✔
514
    streamTaskSendRetrieveRsp(&req, &rsp);
539✔
515
  }
516

517
  streamMetaReleaseTask(pMeta, pTask);
539✔
518
  tCleanupStreamRetrieveReq(&req);
540✔
519

520
  // always return success, to disable the auto rsp
521
  return code;
540✔
522
}
523

524
int32_t tqStreamTaskProcessCheckReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
23,567✔
525
  char*   msgStr = pMsg->pCont;
23,567✔
526
  char*   msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead));
23,567✔
527
  int32_t msgLen = pMsg->contLen - sizeof(SMsgHead);
23,567✔
528
  int32_t code = 0;
23,567✔
529

530
  SStreamTaskCheckReq req;
531
  SStreamTaskCheckRsp rsp = {0};
23,567✔
532

533
  SDecoder decoder;
534

535
  tDecoderInit(&decoder, (uint8_t*)msgBody, msgLen);
23,567✔
536
  code = tDecodeStreamTaskCheckReq(&decoder, &req);
23,562✔
537
  tDecoderClear(&decoder);
23,563✔
538

539
  if (code) {
23,570!
540
    tqError("vgId:%d decode check msg failed, not handle this msg", pMeta->vgId);
×
541
    return code;
×
542
  }
543

544
  streamTaskProcessCheckMsg(pMeta, &req, &rsp);
23,570✔
545
  return streamTaskSendCheckRsp(pMeta, req.upstreamNodeId, &rsp, &pMsg->info, req.upstreamTaskId);
23,597✔
546
}
547

548
int32_t tqStreamTaskProcessCheckRsp(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLeader) {
23,581✔
549
  char*   pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
23,581✔
550
  int32_t len = pMsg->contLen - sizeof(SMsgHead);
23,581✔
551
  int32_t vgId = pMeta->vgId;
23,581✔
552
  int32_t code = TSDB_CODE_SUCCESS;
23,581✔
553

554
  SStreamTaskCheckRsp rsp;
555

556
  SDecoder decoder;
557
  tDecoderInit(&decoder, (uint8_t*)pReq, len);
23,581✔
558
  code = tDecodeStreamTaskCheckRsp(&decoder, &rsp);
23,580✔
559
  if (code < 0) {
23,557!
560
    terrno = TSDB_CODE_INVALID_MSG;
×
561
    tDecoderClear(&decoder);
×
562
    tqError("vgId:%d failed to parse check rsp msg, code:%s", vgId, tstrerror(terrno));
×
563
    return -1;
×
564
  }
565

566
  tDecoderClear(&decoder);
23,557✔
567
  tqDebug("tq task:0x%x (vgId:%d) recv check rsp(QID:0x%" PRIx64 ") from 0x%x (vgId:%d) status %d", rsp.upstreamTaskId,
23,578✔
568
          rsp.upstreamNodeId, rsp.reqId, rsp.downstreamTaskId, rsp.downstreamNodeId, rsp.status);
569

570
  if (!isLeader) {
23,579!
571
    tqError("vgId:%d not leader, task:0x%x not handle the check rsp, downstream:0x%x (vgId:%d)", vgId,
×
572
            rsp.upstreamTaskId, rsp.downstreamTaskId, rsp.downstreamNodeId);
573
    return streamMetaAddFailedTask(pMeta, rsp.streamId, rsp.upstreamTaskId, true);
×
574
  }
575

576
  SStreamTask* pTask = NULL;
23,579✔
577
  code = streamMetaAcquireTask(pMeta, rsp.streamId, rsp.upstreamTaskId, &pTask);
23,579✔
578
  if ((pTask == NULL) || (code != 0)) {
23,583!
579
    return streamMetaAddFailedTask(pMeta, rsp.streamId, rsp.upstreamTaskId, true);
49✔
580
  }
581

582
  code = streamTaskProcessCheckRsp(pTask, &rsp);
23,534✔
583
  streamMetaReleaseTask(pMeta, pTask);
23,529✔
584
  return code;
23,535✔
585
}
586

587
int32_t tqStreamTaskProcessCheckpointReadyMsg(SStreamMeta* pMeta, SRpcMsg* pMsg) {
9,692✔
588
  int32_t vgId = pMeta->vgId;
9,692✔
589
  char*   msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
9,692✔
590
  int32_t len = pMsg->contLen - sizeof(SMsgHead);
9,692✔
591
  int32_t code = 0;
9,692✔
592

593
  SStreamCheckpointReadyMsg req = {0};
9,692✔
594

595
  SDecoder decoder;
596
  tDecoderInit(&decoder, (uint8_t*)msg, len);
9,692✔
597
  if (tDecodeStreamCheckpointReadyMsg(&decoder, &req) < 0) {
9,692!
598
    code = TSDB_CODE_MSG_DECODE_ERROR;
×
599
    tDecoderClear(&decoder);
×
600
    return code;
×
601
  }
602
  tDecoderClear(&decoder);
9,679✔
603

604
  SStreamTask* pTask = NULL;
9,688✔
605
  code = streamMetaAcquireTask(pMeta, req.streamId, req.upstreamTaskId, &pTask);
9,688✔
606
  if (code != 0) {
9,692!
607
    tqError("vgId:%d failed to find s-task:0x%x, it may have been destroyed already", vgId, req.downstreamTaskId);
×
608
    return code;
×
609
  }
610

611
  if (pTask->info.taskLevel == TASK_LEVEL__SINK) {
9,692!
612
    tqDebug("vgId:%d s-task:%s recv invalid the checkpoint-ready msg from task:0x%x (vgId:%d), discard", vgId,
×
613
            pTask->id.idStr, req.downstreamTaskId, req.downstreamNodeId);
614
    streamMetaReleaseTask(pMeta, pTask);
×
615
    return TSDB_CODE_INVALID_MSG;
×
616
  } else {
617
    tqDebug("vgId:%d s-task:%s received the checkpoint-ready msg from task:0x%x (vgId:%d), handle it", vgId,
9,692✔
618
            pTask->id.idStr, req.downstreamTaskId, req.downstreamNodeId);
619
  }
620

621
  code = streamProcessCheckpointReadyMsg(pTask, req.checkpointId, req.downstreamNodeId, req.downstreamTaskId);
9,692✔
622
  streamMetaReleaseTask(pMeta, pTask);
9,689✔
623
  if (code) {
9,694!
624
    return code;
×
625
  }
626

627
  {  // send checkpoint ready rsp
628
    SMStreamCheckpointReadyRspMsg* pReadyRsp = rpcMallocCont(sizeof(SMStreamCheckpointReadyRspMsg));
9,694✔
629
    if (pReadyRsp == NULL) {
9,684!
630
      return terrno;
×
631
    }
632

633
    pReadyRsp->upstreamTaskId = req.upstreamTaskId;
9,684✔
634
    pReadyRsp->upstreamNodeId = req.upstreamNodeId;
9,684✔
635
    pReadyRsp->downstreamTaskId = req.downstreamTaskId;
9,684✔
636
    pReadyRsp->downstreamNodeId = req.downstreamNodeId;
9,684✔
637
    pReadyRsp->checkpointId = req.checkpointId;
9,684✔
638
    pReadyRsp->streamId = req.streamId;
9,684✔
639
    pReadyRsp->head.vgId = htonl(req.downstreamNodeId);
9,684✔
640

641
    SRpcMsg rsp = {.code = 0, .info = pMsg->info, .pCont = pReadyRsp, .contLen = sizeof(SMStreamCheckpointReadyRspMsg)};
9,684✔
642
    tmsgSendRsp(&rsp);
9,684✔
643

644
    pMsg->info.handle = NULL;  // disable auto rsp
9,694✔
645
  }
646

647
  return code;
9,694✔
648
}
649

650
int32_t tqStreamTaskProcessDeployReq(SStreamMeta* pMeta, SMsgCb* cb, int64_t sversion, char* msg, int32_t msgLen,
14,208✔
651
                                     bool isLeader, bool restored) {
652
  int32_t code = 0;
14,208✔
653
  int32_t vgId = pMeta->vgId;
14,208✔
654
  int32_t numOfTasks = 0;
14,208✔
655
  int32_t taskId = -1;
14,208✔
656
  int64_t streamId = -1;
14,208✔
657
  bool    added = false;
14,208✔
658
  int32_t size = sizeof(SStreamTask);
14,208✔
659

660
  if (tsDisableStream) {
14,208!
661
    tqInfo("vgId:%d stream disabled, not deploy stream tasks", vgId);
×
662
    return code;
×
663
  }
664

665
  tqDebug("vgId:%d receive new stream task deploy msg, start to build stream task", vgId);
14,208✔
666

667
  // 1.deserialize msg and build task
668
  SStreamTask* pTask = taosMemoryCalloc(1, size);
14,208!
669
  if (pTask == NULL) {
14,227!
670
    tqError("vgId:%d failed to create stream task due to out of memory, alloc size:%d", vgId, size);
×
671
    return terrno;
×
672
  }
673

674
  SDecoder decoder;
675
  tDecoderInit(&decoder, (uint8_t*)msg, msgLen);
14,227✔
676
  code = tDecodeStreamTask(&decoder, pTask);
14,228✔
677
  tDecoderClear(&decoder);
14,221✔
678

679
  if (code != TSDB_CODE_SUCCESS) {
14,216!
680
    taosMemoryFree(pTask);
×
681
    return TSDB_CODE_INVALID_MSG;
×
682
  }
683

684
  // 2.save task, use the latest commit version as the initial start version of stream task.
685
  taskId = pTask->id.taskId;
14,216✔
686
  streamId = pTask->id.streamId;
14,216✔
687

688
  streamMetaWLock(pMeta);
14,216✔
689
  code = streamMetaRegisterTask(pMeta, sversion, pTask, &added);
14,224✔
690
  numOfTasks = streamMetaGetNumOfTasks(pMeta);
14,231✔
691
  streamMetaWUnLock(pMeta);
14,231✔
692

693
  if (code < 0) {
14,231!
694
    tqError("vgId:%d failed to register s-task:0x%x into meta, existed tasks:%d, code:%s", vgId, taskId, numOfTasks,
×
695
            tstrerror(code));
696
    return code;
×
697
  }
698

699
  // added into meta store, pTask cannot be reference since it may have been destroyed by other threads already now if
700
  // it is added into the meta store
701
  if (added) {
14,231!
702
    // only handled in the leader node
703
    if (isLeader) {
14,231✔
704
      tqDebug("vgId:%d s-task:0x%x is deployed and add into meta, numOfTasks:%d", vgId, taskId, numOfTasks);
14,179✔
705

706
      if (restored) {
14,179✔
707
        SStreamTask* p = NULL;
14,175✔
708
        code = streamMetaAcquireTask(pMeta, streamId, taskId, &p);
14,175✔
709
        if ((p != NULL) && (code == 0) && (p->info.fillHistory == 0)) {
14,174!
710
          code = tqStreamStartOneTaskAsync(pMeta, cb, streamId, taskId);
9,309✔
711
        }
712

713
        if (p != NULL) {
14,174!
714
          streamMetaReleaseTask(pMeta, p);
14,174✔
715
        }
716
      } else {
717
        tqWarn("s-task:0x%x not launched since vnode(vgId:%d) not ready", taskId, vgId);
4!
718
      }
719

720
    } else {
721
      tqDebug("vgId:%d not leader, not launch stream task s-task:0x%x", vgId, taskId);
52!
722
    }
723
  } else {
UNCOV
724
    tqWarn("vgId:%d failed to add s-task:0x%x, since already exists in meta store, total:%d", vgId, taskId, numOfTasks);
×
725
  }
726

727
  return code;
14,231✔
728
}
729

730
int32_t tqStreamTaskProcessDropReq(SStreamMeta* pMeta, char* msg, int32_t msgLen) {
7,020✔
731
  SVDropStreamTaskReq* pReq = (SVDropStreamTaskReq*)msg;
7,020✔
732
  int32_t              code = 0;
7,020✔
733
  int32_t              vgId = pMeta->vgId;
7,020✔
734
  STaskId              hTaskId = {0};
7,020✔
735
  SStreamTask*         pTask = NULL;
7,020✔
736

737
  tqDebug("vgId:%d receive msg to drop s-task:0x%x", vgId, pReq->taskId);
7,020✔
738

739
  streamMetaWLock(pMeta);
7,020✔
740

741
  STaskId id = {.streamId = pReq->streamId, .taskId = pReq->taskId};
7,040✔
742
  code = streamMetaAcquireTaskUnsafe(pMeta, &id, &pTask);
7,040✔
743
  if (code == 0) {
7,038!
744
    if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
7,039✔
745
      hTaskId.streamId = pTask->hTaskInfo.id.streamId;
1,366✔
746
      hTaskId.taskId = pTask->hTaskInfo.id.taskId;
1,366✔
747
    }
748

749
    // clear the relationship, and then release the stream tasks, to avoid invalid accessing of already freed
750
    // related stream(history) task
751
    streamTaskSetRemoveBackendFiles(pTask);
7,039✔
752
    code = streamTaskClearHTaskAttr(pTask, pReq->resetRelHalt);
7,027✔
753
    streamMetaReleaseTask(pMeta, pTask);
7,033✔
754

755
    if (code) {
7,039!
756
      tqError("s-task:0x%x failed to clear related fill-history info, still exists", pReq->taskId);
×
757
    }
758
  }
759

760
  // drop the related fill-history task firstly
761
  if (hTaskId.taskId != 0 && hTaskId.streamId != 0) {
7,038!
762
    tqDebug("s-task:0x%x vgId:%d drop rel fill-history task:0x%x firstly", pReq->taskId, vgId, (int32_t)hTaskId.taskId);
1,367✔
763
    code = streamMetaUnregisterTask(pMeta, hTaskId.streamId, hTaskId.taskId);
1,367✔
764
    if (code) {
1,366!
765
      tqDebug("s-task:0x%x vgId:%d drop rel fill-history task:0x%x failed", pReq->taskId, vgId,
×
766
              (int32_t)hTaskId.taskId);
767
    }
768
  }
769

770
  // drop the stream task now
771
  code = streamMetaUnregisterTask(pMeta, pReq->streamId, pReq->taskId);
7,037✔
772
  if (code) {
7,036!
773
    tqDebug("s-task:0x%x vgId:%d drop task failed", pReq->taskId, vgId);
×
774
  }
775

776
  // commit the update
777
  int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta);
7,036✔
778
  tqDebug("vgId:%d task:0x%x dropped, remain tasks:%d", vgId, pReq->taskId, numOfTasks);
7,042✔
779
  if (numOfTasks == 0) {
7,042✔
780
    streamMetaResetStartInfo(&pMeta->startInfo, vgId);
1,640✔
781
  }
782

783
  if (streamMetaCommit(pMeta) < 0) {
7,042✔
784
    // persist to disk
785
  }
786

787
  streamMetaWUnLock(pMeta);
7,046✔
788
  tqDebug("vgId:%d process drop task:0x%x completed", vgId, pReq->taskId);
7,046✔
789

790
  return 0;  // always return success
7,046✔
791
}
792

793
int32_t tqStreamTaskProcessUpdateCheckpointReq(SStreamMeta* pMeta, bool restored, char* msg) {
6,524✔
794
  SVUpdateCheckpointInfoReq* pReq = (SVUpdateCheckpointInfoReq*)msg;
6,524✔
795
  int32_t                    code = 0;
6,524✔
796
  int32_t                    vgId = pMeta->vgId;
6,524✔
797
  SStreamTask*               pTask = NULL;
6,524✔
798

799
  tqDebug("vgId:%d receive msg to update-checkpoint-info for s-task:0x%x", vgId, pReq->taskId);
6,524✔
800

801
  streamMetaWLock(pMeta);
6,524✔
802

803
  STaskId id = {.streamId = pReq->streamId, .taskId = pReq->taskId};
6,524✔
804
  code = streamMetaAcquireTaskUnsafe(pMeta, &id, &pTask);
6,524✔
805
  if (code == 0) {
6,527!
806
    code = streamTaskUpdateTaskCheckpointInfo(pTask, restored, pReq);
6,527✔
807
    streamMetaReleaseTask(pMeta, pTask);
6,529✔
808
  } else {  // failed to get the task.
809
    int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta);
×
810
    tqError(
×
811
        "vgId:%d failed to locate the s-task:0x%x to update the checkpoint info, numOfTasks:%d, it may have been "
812
        "dropped already",
813
        vgId, pReq->taskId, numOfTasks);
814
  }
815

816
  streamMetaWUnLock(pMeta);
6,529✔
817
  // always return success when handling the requirement issued by mnode during transaction.
818
  return TSDB_CODE_SUCCESS;
6,529✔
819
}
820

821
static int32_t restartStreamTasks(SStreamMeta* pMeta, bool isLeader) {
14✔
822
  int32_t         vgId = pMeta->vgId;
14✔
823
  int32_t         code = 0;
14✔
824
  int64_t         st = taosGetTimestampMs();
14✔
825
  STaskStartInfo* pStartInfo = &pMeta->startInfo;
14✔
826

827
  if (pStartInfo->startAllTasks == 1) {
14✔
828
    // wait for the checkpoint id rsp, this rsp will be expired
829
    if (pStartInfo->curStage == START_MARK_REQ_CHKPID) {
3!
830
      SStartTaskStageInfo* pCurStageInfo = taosArrayGetLast(pStartInfo->pStagesList);
×
831
      tqInfo("vgId:%d only mark the req consensus checkpointId flag, reqTs:%"PRId64 " ignore and continue", vgId, pCurStageInfo->ts);
×
832

833
      taosArrayClear(pStartInfo->pStagesList);
×
834
      pStartInfo->curStage = 0;
×
835
      goto _start;
×
836

837
    } else if (pStartInfo->curStage == START_WAIT_FOR_CHKPTID) {
3!
838
      SStartTaskStageInfo* pCurStageInfo = taosArrayGetLast(pStartInfo->pStagesList);
3✔
839
      tqInfo("vgId:%d already sent consensus-checkpoint msg(waiting for chkptid) expired, reqTs:%" PRId64
3!
840
             " rsp will be discarded",
841
             vgId, pCurStageInfo->ts);
842

843
      taosArrayClear(pStartInfo->pStagesList);
3✔
844
      pStartInfo->curStage = 0;
3✔
845
      goto _start;
3✔
846

847
    } else if (pStartInfo->curStage == START_CHECK_DOWNSTREAM) {
×
848
      pStartInfo->restartCount += 1;
×
849
      tqDebug(
×
850
          "vgId:%d in start tasks procedure (check downstream), inc restartCounter by 1 and wait for it completes, "
851
          "remaining restart:%d",
852
          vgId, pStartInfo->restartCount);
853
    } else {
854
      tqInfo("vgId:%d in start procedure, but not start to do anything yet, do nothing", vgId);
×
855
    }
856

857
    return TSDB_CODE_SUCCESS;
×
858
  }
859

860
_start:
11✔
861

862
  pStartInfo->startAllTasks = 1;
14✔
863
  terrno = 0;
14✔
864
  tqInfo("vgId:%d tasks are all updated and stopped, restart all tasks, triggered by transId:%d, ts:%" PRId64, vgId,
14!
865
         pMeta->updateInfo.completeTransId, pMeta->updateInfo.completeTs);
866

867
  streamMetaClear(pMeta);
14✔
868

869
  int64_t el = taosGetTimestampMs() - st;
14✔
870
  tqInfo("vgId:%d clear&close stream meta completed, elapsed time:%.3fs", vgId, el / 1000.);
14!
871

872
  streamMetaLoadAllTasks(pMeta);
14✔
873

874
  if (isLeader && !tsDisableStream) {
14!
875
    code = streamMetaStartAllTasks(pMeta);
14✔
876
  } else {
877
    streamMetaResetStartInfo(&pMeta->startInfo, pMeta->vgId);
×
878
    pStartInfo->restartCount = 0;
×
879
    tqInfo("vgId:%d, follower node not start stream tasks or stream is disabled", vgId);
×
880
  }
881

882
  code = terrno;
14✔
883
  return code;
14✔
884
}
885

886
int32_t tqStreamTaskProcessRunReq(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLeader) {
96,525✔
887
  int32_t  code = 0;
96,525✔
888
  int32_t  vgId = pMeta->vgId;
96,525✔
889
  char*    msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
96,525✔
890
  int32_t  len = pMsg->contLen - sizeof(SMsgHead);
96,525✔
891
  SDecoder decoder;
892

893
  SStreamTaskRunReq req = {0};
96,525✔
894
  tDecoderInit(&decoder, (uint8_t*)msg, len);
96,525✔
895
  if ((code = tDecodeStreamTaskRunReq(&decoder, &req)) < 0) {
96,647!
896
    tqError("vgId:%d failed to decode task run req, code:%s", pMeta->vgId, tstrerror(code));
×
897
    tDecoderClear(&decoder);
×
898
    return TSDB_CODE_SUCCESS;
×
899
  }
900

901
  tDecoderClear(&decoder);
96,653✔
902

903
  int32_t type = req.reqType;
96,657✔
904
  if (type == STREAM_EXEC_T_START_ONE_TASK) {
96,657✔
905
    code = streamMetaStartOneTask(pMeta, req.streamId, req.taskId);
9,467✔
906
    return 0;
9,460✔
907
  } else if (type == STREAM_EXEC_T_START_ALL_TASKS) {
87,190✔
908
    streamMetaWLock(pMeta);
10,813✔
909
    code = streamMetaStartAllTasks(pMeta);
10,813✔
910
    streamMetaWUnLock(pMeta);
10,814✔
911
    return 0;
10,814✔
912
  } else if (type == STREAM_EXEC_T_RESTART_ALL_TASKS) {
76,377✔
913
    streamMetaWLock(pMeta);
14✔
914
    code = restartStreamTasks(pMeta, isLeader);
14✔
915
    streamMetaWUnLock(pMeta);
14✔
916
    return 0;
15✔
917
  } else if (type == STREAM_EXEC_T_STOP_ALL_TASKS) {
76,363✔
918
    code = streamMetaStopAllTasks(pMeta);
4,806✔
919
    return 0;
4,809✔
920
  } else if (type == STREAM_EXEC_T_ADD_FAILED_TASK) {
71,557!
UNCOV
921
    code = streamMetaAddFailedTask(pMeta, req.streamId, req.taskId, true);
×
UNCOV
922
    return code;
×
923
  } else if (type == STREAM_EXEC_T_STOP_ONE_TASK) {
71,557!
924
    code = streamMetaStopOneTask(pMeta, req.streamId, req.taskId);
×
925
    return code;
×
926
  } else if (type == STREAM_EXEC_T_RESUME_TASK) {  // task resume to run after idle for a while
71,557✔
927
    SStreamTask* pTask = NULL;
8,209✔
928
    code = streamMetaAcquireTask(pMeta, req.streamId, req.taskId, &pTask);
8,209✔
929

930
    if (pTask != NULL && (code == 0)) {
8,211!
931
      char* pStatus = NULL;
8,207✔
932
      if (streamTaskReadyToRun(pTask, &pStatus)) {
8,207!
933
        int64_t execTs = pTask->status.lastExecTs;
8,207✔
934
        int32_t idle = taosGetTimestampMs() - execTs;
8,204✔
935
        tqDebug("s-task:%s task resume to run after idle for:%dms from:%" PRId64, pTask->id.idStr, idle, execTs);
8,204✔
936

937
        code = streamResumeTask(pTask);
8,204✔
938
      } else {
939
        int8_t status = streamTaskSetSchedStatusInactive(pTask);
×
940
        tqDebug("vgId:%d s-task:%s ignore run req since not in ready state, status:%s, sched-status:%d", vgId,
×
941
                pTask->id.idStr, pStatus, status);
942
      }
943
      streamMetaReleaseTask(pMeta, pTask);
8,205✔
944
    }
945

946
    return code;
8,212✔
947
  }
948

949
  SStreamTask* pTask = NULL;
63,348✔
950
  code = streamMetaAcquireTask(pMeta, req.streamId, req.taskId, &pTask);
63,348✔
951
  if ((pTask != NULL) && (code == 0)) {  // even in halt status, the data in inputQ must be processed
63,330✔
952
    char* p = NULL;
63,318✔
953
    if (streamTaskReadyToRun(pTask, &p)) {
63,318✔
954
      tqDebug("vgId:%d s-task:%s status:%s start to process block from inputQ, next checked ver:%" PRId64, vgId,
63,279✔
955
              pTask->id.idStr, p, pTask->chkInfo.nextProcessVer);
956
      (void)streamExecTask(pTask);
63,279✔
957
    } else {
958
      int8_t status = streamTaskSetSchedStatusInactive(pTask);
23✔
959
      tqDebug("vgId:%d s-task:%s ignore run req since not in ready state, status:%s, sched-status:%d", vgId,
26!
960
              pTask->id.idStr, p, status);
961
    }
962

963
    streamMetaReleaseTask(pMeta, pTask);
63,322✔
964
    return 0;
63,325✔
965
  } else {  // NOTE: pTask->status.schedStatus is not updated since it is not be handled by the run exec.
966
    // todo add one function to handle this
967
    tqError("vgId:%d failed to found s-task, taskId:0x%x may have been dropped", vgId, req.taskId);
12✔
968
    return code;
8✔
969
  }
970
}
971

972
int32_t tqStartTaskCompleteCallback(SStreamMeta* pMeta) {
57✔
973
  STaskStartInfo* pStartInfo = &pMeta->startInfo;
57✔
974
  int32_t         vgId = pMeta->vgId;
57✔
975
  bool            scanWal = false;
57✔
976
  int32_t         code = 0;
57✔
977

978
//  streamMetaWLock(pMeta);
979
  if (pStartInfo->startAllTasks == 1) {
57!
980
    tqDebug("vgId:%d already in start tasks procedure in other thread, restartCounter:%d, do nothing", vgId,
×
981
            pMeta->startInfo.restartCount);
982
  } else {  // not in starting procedure
983
    bool allReady = streamMetaAllTasksReady(pMeta);
57✔
984

985
    if ((pStartInfo->restartCount > 0) && (!allReady)) {
57!
986
      // if all tasks are ready now, do NOT restart again, and reset the value of pStartInfo->restartCount
987
      pStartInfo->restartCount -= 1;
×
988
      tqDebug("vgId:%d role:%d need to restart all tasks again, restartCounter:%d", vgId, pMeta->role,
×
989
              pStartInfo->restartCount);
990
//      streamMetaWUnLock(pMeta);
991

992
      return restartStreamTasks(pMeta, (pMeta->role == NODE_ROLE_LEADER));
×
993
    } else {
994
      if (pStartInfo->restartCount == 0) {
57!
995
        tqDebug("vgId:%d start all tasks completed in callbackFn, restartCounter is 0", pMeta->vgId);
57✔
996
      } else if (allReady) {
×
997
        pStartInfo->restartCount = 0;
×
998
        tqDebug("vgId:%d all tasks are ready, reset restartCounter 0, not restart tasks", vgId);
×
999
      }
1000

1001
      scanWal = true;
57✔
1002
    }
1003
  }
1004

1005
//  streamMetaWUnLock(pMeta);
1006

1007
  return code;
57✔
1008
}
1009

1010
int32_t tqStreamTaskProcessTaskResetReq(SStreamMeta* pMeta, char* pMsg) {
×
1011
  SVResetStreamTaskReq* pReq = (SVResetStreamTaskReq*)pMsg;
×
1012

1013
  SStreamTask* pTask = NULL;
×
1014
  int32_t      code = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId, &pTask);
×
1015
  if (pTask == NULL || (code != 0)) {
×
1016
    tqError("vgId:%d process task-reset req, failed to acquire task:0x%x, it may have been dropped already",
×
1017
            pMeta->vgId, pReq->taskId);
1018
    return TSDB_CODE_SUCCESS;
×
1019
  }
1020

1021
  tqDebug("s-task:%s receive task-reset msg from mnode, reset status and ready for data processing", pTask->id.idStr);
×
1022

1023
  streamMutexLock(&pTask->lock);
×
1024

1025
  streamTaskSetFailedCheckpointId(pTask, pReq->chkptId);
×
1026
  streamTaskClearCheckInfo(pTask, true);
×
1027

1028
  // clear flag set during do checkpoint, and open inputQ for all upstream tasks
1029
  SStreamTaskState pState = streamTaskGetStatus(pTask);
×
1030
  if (pState.state == TASK_STATUS__CK) {
×
1031
    streamTaskSetStatusReady(pTask);
×
1032
    tqDebug("s-task:%s reset checkpoint status to ready", pTask->id.idStr);
×
1033
  } else if (pState.state == TASK_STATUS__UNINIT) {
×
1034
    //    tqDebug("s-task:%s start task by checking downstream tasks", pTask->id.idStr);
1035
    //    tqStreamTaskRestoreCheckpoint(pMeta, pTask->id.streamId, pTask->id.taskId);
1036
    tqDebug("s-task:%s status:%s do nothing after receiving reset-task from mnode", pTask->id.idStr, pState.name);
×
1037
  } else {
1038
    tqDebug("s-task:%s status:%s do nothing after receiving reset-task from mnode", pTask->id.idStr, pState.name);
×
1039
  }
1040

1041
  streamMutexUnlock(&pTask->lock);
×
1042

1043
  streamMetaReleaseTask(pMeta, pTask);
×
1044
  return TSDB_CODE_SUCCESS;
×
1045
}
1046

1047
int32_t tqStreamTaskProcessAllTaskStopReq(SStreamMeta* pMeta, SMsgCb* pMsgCb, SRpcMsg* pMsg) {
4,739✔
1048
  int32_t  code = 0;
4,739✔
1049
  int32_t  vgId = pMeta->vgId;
4,739✔
1050
  char*    msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
4,739✔
1051
  int32_t  len = pMsg->contLen - sizeof(SMsgHead);
4,739✔
1052
  SDecoder decoder;
1053

1054
  SStreamTaskStopReq req = {0};
4,739✔
1055
  tDecoderInit(&decoder, (uint8_t*)msg, len);
4,739✔
1056
  if ((code = tDecodeStreamTaskStopReq(&decoder, &req)) < 0) {
4,735!
1057
    tqError("vgId:%d failed to decode stop all streams, code:%s", pMeta->vgId, tstrerror(code));
×
1058
    tDecoderClear(&decoder);
×
1059
    return TSDB_CODE_SUCCESS;
×
1060
  }
1061

1062
  tDecoderClear(&decoder);
4,736✔
1063

1064
  // stop all stream tasks, only invoked when trying to drop db
1065
  if (req.streamId <= 0) {
4,736!
1066
    tqDebug("vgId:%d recv msg to stop all tasks in sync before dropping vnode", vgId);
4,744✔
1067
    code = streamMetaStopAllTasks(pMeta);
4,748✔
1068
    if (code) {
4,742!
1069
      tqError("vgId:%d failed to stop all tasks, code:%s", vgId, tstrerror(code));
×
1070
    }
1071

1072
  } else {  // stop only one stream tasks
1073

1074
  }
1075

1076
  // always return success
1077
  return TSDB_CODE_SUCCESS;
4,743✔
1078
}
1079

1080
int32_t tqStreamTaskProcessRetrieveTriggerReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
×
1081
  SRetrieveChkptTriggerReq req = {0};
×
1082
  SStreamTask*             pTask = NULL;
×
1083
  char*                    msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
×
1084
  int32_t                  len = pMsg->contLen - sizeof(SMsgHead);
×
1085
  SDecoder                 decoder = {0};
×
1086

1087
  tDecoderInit(&decoder, (uint8_t*)msg, len);
×
1088
  if (tDecodeRetrieveChkptTriggerReq(&decoder, &req) < 0) {
×
1089
    tDecoderClear(&decoder);
×
1090
    tqError("vgId:%d invalid retrieve checkpoint-trigger req received", pMeta->vgId);
×
1091
    return TSDB_CODE_INVALID_MSG;
×
1092
  }
1093
  tDecoderClear(&decoder);
×
1094

1095
  int32_t code = streamMetaAcquireTask(pMeta, req.streamId, req.upstreamTaskId, &pTask);
×
1096
  if (pTask == NULL || (code != 0)) {
×
1097
    tqError("vgId:%d process retrieve checkpoint-trigger, checkpointId:%" PRId64
×
1098
            " from s-task:0x%x, failed to acquire task:0x%x, it may have been dropped already",
1099
            pMeta->vgId, req.checkpointId, (int32_t)req.downstreamTaskId, req.upstreamTaskId);
1100
    return TSDB_CODE_STREAM_TASK_NOT_EXIST;
×
1101
  }
1102

1103
  tqDebug("s-task:0x%x recv retrieve checkpoint-trigger msg from downstream s-task:0x%x, checkpointId:%" PRId64,
×
1104
          req.upstreamTaskId, (int32_t)req.downstreamTaskId, req.checkpointId);
1105

1106
  if (pTask->status.downstreamReady != 1) {
×
1107
    tqError("s-task:%s not ready for checkpoint-trigger retrieve from 0x%x, since downstream not ready",
×
1108
            pTask->id.idStr, (int32_t)req.downstreamTaskId);
1109

1110
    code = streamTaskSendCheckpointTriggerMsg(pTask, req.downstreamTaskId, req.downstreamNodeId, &pMsg->info,
×
1111
                                              TSDB_CODE_STREAM_TASK_IVLD_STATUS);
1112
    streamMetaReleaseTask(pMeta, pTask);
×
1113
    return code;
×
1114
  }
1115

1116
  SStreamTaskState pState = streamTaskGetStatus(pTask);
×
1117
  if (pState.state == TASK_STATUS__CK) {  // recv the checkpoint-source/trigger already
×
1118
    int32_t transId = 0;
×
1119
    int64_t checkpointId = 0;
×
1120

1121
    streamTaskGetActiveCheckpointInfo(pTask, &transId, &checkpointId);
×
1122
    if (checkpointId != req.checkpointId) {
×
1123
      tqError("s-task:%s invalid checkpoint-trigger retrieve msg from 0x%" PRIx64 ", current checkpointId:%" PRId64
×
1124
              " req:%" PRId64,
1125
              pTask->id.idStr, req.downstreamTaskId, checkpointId, req.checkpointId);
1126
      streamMetaReleaseTask(pMeta, pTask);
×
1127
      return TSDB_CODE_INVALID_MSG;
×
1128
    }
1129

1130
    if (streamTaskAlreadySendTrigger(pTask, req.downstreamNodeId)) {
×
1131
      // re-send the lost checkpoint-trigger msg to downstream task
1132
      tqDebug("s-task:%s re-send checkpoint-trigger to:0x%x, checkpointId:%" PRId64 ", transId:%d", pTask->id.idStr,
×
1133
              (int32_t)req.downstreamTaskId, checkpointId, transId);
1134
      code = streamTaskSendCheckpointTriggerMsg(pTask, req.downstreamTaskId, req.downstreamNodeId, &pMsg->info,
×
1135
                                                TSDB_CODE_SUCCESS);
1136
    } else {  // not send checkpoint-trigger yet, wait
1137
      int32_t recv = 0, total = 0;
×
1138
      streamTaskGetTriggerRecvStatus(pTask, &recv, &total);
×
1139

1140
      if (recv == total) {  // add the ts info
×
1141
        tqWarn("s-task:%s all upstream send checkpoint-source/trigger, but not processed yet, wait", pTask->id.idStr);
×
1142
      } else {
1143
        tqWarn(
×
1144
            "s-task:%s not all upstream send checkpoint-source/trigger, total recv:%d/%d, wait for all upstream "
1145
            "sending checkpoint-source/trigger",
1146
            pTask->id.idStr, recv, total);
1147
      }
1148
      code = streamTaskSendCheckpointTriggerMsg(pTask, req.downstreamTaskId, req.downstreamNodeId, &pMsg->info,
×
1149
                                                TSDB_CODE_ACTION_IN_PROGRESS);
1150
    }
1151
  } else {  // upstream not recv the checkpoint-source/trigger till now
1152
    if (!(pState.state == TASK_STATUS__READY || pState.state == TASK_STATUS__HALT)) {
×
1153
      tqFatal("s-task:%s invalid task status:%s", pTask->id.idStr, pState.name);
×
1154
    }
1155

1156
    tqWarn(
×
1157
        "s-task:%s not recv checkpoint-source from mnode or checkpoint-trigger from upstream yet, wait for all "
1158
        "upstream sending checkpoint-source/trigger",
1159
        pTask->id.idStr);
1160
    code = streamTaskSendCheckpointTriggerMsg(pTask, req.downstreamTaskId, req.downstreamNodeId, &pMsg->info,
×
1161
                                              TSDB_CODE_ACTION_IN_PROGRESS);
1162
  }
1163

1164
  streamMetaReleaseTask(pMeta, pTask);
×
1165
  return code;
×
1166
}
1167

1168
int32_t tqStreamTaskProcessRetrieveTriggerRsp(SStreamMeta* pMeta, SRpcMsg* pMsg) {
×
1169
  SCheckpointTriggerRsp rsp = {0};
×
1170
  SStreamTask*          pTask = NULL;
×
1171
  char*                 msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
×
1172
  int32_t               len = pMsg->contLen - sizeof(SMsgHead);
×
1173
  SDecoder              decoder = {0};
×
1174

1175
  tDecoderInit(&decoder, (uint8_t*)msg, len);
×
1176
  if (tDecodeCheckpointTriggerRsp(&decoder, &rsp) < 0) {
×
1177
    tDecoderClear(&decoder);
×
1178
    tqError("vgId:%d invalid retrieve checkpoint-trigger rsp received", pMeta->vgId);
×
1179
    return TSDB_CODE_INVALID_MSG;
×
1180
  }
1181
  tDecoderClear(&decoder);
×
1182

1183
  int32_t code = streamMetaAcquireTask(pMeta, rsp.streamId, rsp.taskId, &pTask);
×
1184
  if (pTask == NULL || (code != 0)) {
×
1185
    tqError(
×
1186
        "vgId:%d process retrieve checkpoint-trigger, failed to acquire task:0x%x, it may have been dropped already",
1187
        pMeta->vgId, rsp.taskId);
1188
    return code;
×
1189
  }
1190

1191
  tqDebug(
×
1192
      "s-task:%s recv re-send checkpoint-trigger msg through retrieve/rsp channel, upstream:0x%x, checkpointId:%" PRId64
1193
      ", transId:%d",
1194
      pTask->id.idStr, rsp.upstreamTaskId, rsp.checkpointId, rsp.transId);
1195

1196
  code = streamTaskProcessCheckpointTriggerRsp(pTask, &rsp);
×
1197
  streamMetaReleaseTask(pMeta, pTask);
×
1198
  return code;
×
1199
}
1200

1201
int32_t tqStreamTaskProcessTaskPauseReq(SStreamMeta* pMeta, char* pMsg) {
1,412✔
1202
  SVPauseStreamTaskReq* pReq = (SVPauseStreamTaskReq*)pMsg;
1,412✔
1203

1204
  SStreamTask* pTask = NULL;
1,412✔
1205
  int32_t      code = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId, &pTask);
1,412✔
1206
  if (pTask == NULL || (code != 0)) {
1,421!
1207
    tqError("vgId:%d process pause req, failed to acquire task:0x%x, it may have been dropped already", pMeta->vgId,
×
1208
            pReq->taskId);
1209
    // since task is in [STOP|DROPPING] state, it is safe to assume the pause is active
1210
    return TSDB_CODE_SUCCESS;
×
1211
  }
1212

1213
  tqDebug("s-task:%s receive pause msg from mnode", pTask->id.idStr);
1,421✔
1214
  streamTaskPause(pTask);
1,421✔
1215

1216
  SStreamTask* pHistoryTask = NULL;
1,422✔
1217
  if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
1,422!
1218
    pHistoryTask = NULL;
×
1219
    code = streamMetaAcquireTask(pMeta, pTask->hTaskInfo.id.streamId, pTask->hTaskInfo.id.taskId, &pHistoryTask);
×
1220
    if (pHistoryTask == NULL || (code != 0)) {
×
1221
      tqError("vgId:%d process pause req, failed to acquire fill-history task:0x%" PRIx64
×
1222
              ", it may have been dropped already",
1223
              pMeta->vgId, pTask->hTaskInfo.id.taskId);
1224
      streamMetaReleaseTask(pMeta, pTask);
×
1225

1226
      // since task is in [STOP|DROPPING] state, it is safe to assume the pause is active
1227
      return TSDB_CODE_SUCCESS;
×
1228
    }
1229

1230
    tqDebug("s-task:%s fill-history task handle paused along with related stream task", pHistoryTask->id.idStr);
×
1231

1232
    streamTaskPause(pHistoryTask);
×
1233
    streamMetaReleaseTask(pMeta, pHistoryTask);
×
1234
  }
1235

1236
  streamMetaReleaseTask(pMeta, pTask);
1,422✔
1237
  return TSDB_CODE_SUCCESS;
1,422✔
1238
}
1239

1240
static int32_t tqProcessTaskResumeImpl(void* handle, SStreamTask* pTask, int64_t sversion, int8_t igUntreated,
2,589✔
1241
                                       bool fromVnode) {
1242
  SStreamMeta* pMeta = fromVnode ? ((STQ*)handle)->pStreamMeta : handle;
2,589✔
1243
  int32_t      vgId = pMeta->vgId;
2,589✔
1244
  int32_t      code = 0;
2,589✔
1245

1246
  streamTaskResume(pTask);
2,589✔
1247
  ETaskStatus status = streamTaskGetStatus(pTask).state;
2,591✔
1248

1249
  int32_t level = pTask->info.taskLevel;
2,591✔
1250
  if (status == TASK_STATUS__READY || status == TASK_STATUS__SCAN_HISTORY || status == TASK_STATUS__CK) {
2,591!
1251
    // no lock needs to secure the access of the version
1252
    if (igUntreated && level == TASK_LEVEL__SOURCE && !pTask->info.fillHistory) {
2,591!
1253
      // discard all the data  when the stream task is suspended.
1254
      walReaderSetSkipToVersion(pTask->exec.pWalReader, sversion);
589✔
1255
      tqDebug("vgId:%d s-task:%s resume to exec, prev paused version:%" PRId64 ", start from vnode ver:%" PRId64
589✔
1256
              ", schedStatus:%d",
1257
              vgId, pTask->id.idStr, pTask->chkInfo.nextProcessVer, sversion, pTask->status.schedStatus);
1258
    } else {  // from the previous paused version and go on
1259
      tqDebug("vgId:%d s-task:%s resume to exec, from paused ver:%" PRId64 ", vnode ver:%" PRId64 ", schedStatus:%d",
2,002✔
1260
              vgId, pTask->id.idStr, pTask->chkInfo.nextProcessVer, sversion, pTask->status.schedStatus);
1261
    }
1262

1263
    if (level == TASK_LEVEL__SOURCE && pTask->info.fillHistory && status == TASK_STATUS__SCAN_HISTORY) {
2,591!
1264
      pTask->hTaskInfo.operatorOpen = false;
×
1265
      code = streamStartScanHistoryAsync(pTask, igUntreated);
×
1266
    } else if (level == TASK_LEVEL__SOURCE && (streamQueueGetNumOfItems(pTask->inputq.queue) == 0)) {
2,591✔
1267
      //      code = tqScanWalAsync((STQ*)handle, false);
1268
    } else {
1269
      code = streamTrySchedExec(pTask, false);
1,304✔
1270
    }
1271
  }
1272

1273
  return code;
2,591✔
1274
}
1275

1276
int32_t tqStreamTaskProcessTaskResumeReq(void* handle, int64_t sversion, char* msg, bool fromVnode) {
2,586✔
1277
  SVResumeStreamTaskReq* pReq = (SVResumeStreamTaskReq*)msg;
2,586✔
1278

1279
  SStreamMeta* pMeta = fromVnode ? ((STQ*)handle)->pStreamMeta : handle;
2,586✔
1280

1281
  SStreamTask* pTask = NULL;
2,586✔
1282
  int32_t      code = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId, &pTask);
2,586✔
1283
  if (pTask == NULL || (code != 0)) {
2,588!
1284
    tqError("s-task:0x%x failed to acquire task to resume, it may have been dropped or stopped", pReq->taskId);
×
1285
    return TSDB_CODE_STREAM_TASK_IVLD_STATUS;
×
1286
  }
1287

1288
  streamMutexLock(&pTask->lock);
2,588✔
1289
  SStreamTaskState pState = streamTaskGetStatus(pTask);
2,590✔
1290
  tqDebug("s-task:%s start to resume from paused, current status:%s", pTask->id.idStr, pState.name);
2,587✔
1291
  streamMutexUnlock(&pTask->lock);
2,587✔
1292

1293
  code = tqProcessTaskResumeImpl(handle, pTask, sversion, pReq->igUntreated, fromVnode);
2,591✔
1294
  if (code != 0) {
2,591!
1295
    streamMetaReleaseTask(pMeta, pTask);
×
1296
    return code;
×
1297
  }
1298

1299
  STaskId*     pHTaskId = &pTask->hTaskInfo.id;
2,591✔
1300
  SStreamTask* pHTask = NULL;
2,591✔
1301
  code = streamMetaAcquireTask(pMeta, pHTaskId->streamId, pHTaskId->taskId, &pHTask);
2,591✔
1302
  if (pHTask && (code == 0)) {
2,589!
1303
    streamMutexLock(&pHTask->lock);
×
1304
    SStreamTaskState p = streamTaskGetStatus(pHTask);
×
1305
    tqDebug("s-task:%s related history task start to resume from paused, current status:%s", pHTask->id.idStr, p.name);
×
1306
    streamMutexUnlock(&pHTask->lock);
×
1307

1308
    code = tqProcessTaskResumeImpl(handle, pHTask, sversion, pReq->igUntreated, fromVnode);
×
1309
    tqDebug("s-task:%s resume complete, code:%s", pHTask->id.idStr, tstrerror(code));
×
1310

1311
    streamMetaReleaseTask(pMeta, pHTask);
×
1312
  }
1313

1314
  streamMetaReleaseTask(pMeta, pTask);
2,589✔
1315
  return TSDB_CODE_SUCCESS;
2,591✔
1316
}
1317

1318
int32_t tqStreamTasksGetTotalNum(SStreamMeta* pMeta) { return taosArrayGetSize(pMeta->pTaskList); }
×
1319

1320
int32_t doProcessDummyRspMsg(SStreamMeta* UNUSED_PARAM(pMeta), SRpcMsg* pMsg) {
11,611✔
1321
  rpcFreeCont(pMsg->pCont);
11,611✔
1322
  pMsg->pCont = NULL;
11,610✔
1323
  return TSDB_CODE_SUCCESS;
11,610✔
1324
}
1325

1326
int32_t tqStreamProcessStreamHbRsp(SStreamMeta* pMeta, SRpcMsg* pMsg) {
35,274✔
1327
  SMStreamHbRspMsg rsp = {0};
35,274✔
1328
  int32_t          code = 0;
35,274✔
1329
  SDecoder         decoder;
1330
  char*            msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
35,274✔
1331
  int32_t          len = pMsg->contLen - sizeof(SMsgHead);
35,274✔
1332

1333
  tDecoderInit(&decoder, (uint8_t*)msg, len);
35,274✔
1334
  code = tDecodeStreamHbRsp(&decoder, &rsp);
35,242✔
1335
  if (code < 0) {
35,269!
1336
    terrno = TSDB_CODE_INVALID_MSG;
×
1337
    tDecoderClear(&decoder);
×
1338
    tqError("vgId:%d failed to parse hb rsp msg, code:%s", pMeta->vgId, tstrerror(terrno));
×
1339
    return terrno;
×
1340
  }
1341

1342
  tDecoderClear(&decoder);
35,269✔
1343
  return streamProcessHeartbeatRsp(pMeta, &rsp);
35,272✔
1344
}
1345

1346
int32_t tqStreamProcessReqCheckpointRsp(SStreamMeta* pMeta, SRpcMsg* pMsg) { return doProcessDummyRspMsg(pMeta, pMsg); }
4,372✔
1347

1348
int32_t tqStreamProcessChkptReportRsp(SStreamMeta* pMeta, SRpcMsg* pMsg) { return doProcessDummyRspMsg(pMeta, pMsg); }
7,238✔
1349

1350
int32_t tqStreamProcessCheckpointReadyRsp(SStreamMeta* pMeta, SRpcMsg* pMsg) {
9,698✔
1351
  SMStreamCheckpointReadyRspMsg* pRsp = pMsg->pCont;
9,698✔
1352

1353
  SStreamTask* pTask = NULL;
9,698✔
1354
  int32_t      code = streamMetaAcquireTask(pMeta, pRsp->streamId, pRsp->downstreamTaskId, &pTask);
9,698✔
1355
  if (pTask == NULL || (code != 0)) {
9,698!
UNCOV
1356
    tqError("vgId:%d failed to acquire task:0x%x when handling checkpoint-ready msg, it may have been dropped",
×
1357
            pRsp->downstreamNodeId, pRsp->downstreamTaskId);
UNCOV
1358
    return code;
×
1359
  }
1360

1361
  code = streamTaskProcessCheckpointReadyRsp(pTask, pRsp->upstreamTaskId, pRsp->checkpointId);
9,698✔
1362
  streamMetaReleaseTask(pMeta, pTask);
9,700✔
1363
  return code;
9,700✔
1364
}
1365

1366
int32_t tqStreamTaskProcessConsenChkptIdReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
149✔
1367
  int32_t                vgId = pMeta->vgId;
149✔
1368
  int32_t                code = 0;
149✔
1369
  SStreamTask*           pTask = NULL;
149✔
1370
  char*                  msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
149✔
1371
  int32_t                len = pMsg->contLen - sizeof(SMsgHead);
149✔
1372
  int64_t                now = taosGetTimestampMs();
149✔
1373
  SDecoder               decoder;
1374
  SRestoreCheckpointInfo req = {0};
149✔
1375

1376
  tDecoderInit(&decoder, (uint8_t*)msg, len);
149✔
1377
  if ((code = tDecodeRestoreCheckpointInfo(&decoder, &req)) < 0) {
149!
1378
    tqError("vgId:%d failed to decode set consensus checkpointId req, code:%s", vgId, tstrerror(code));
×
1379
    tDecoderClear(&decoder);
×
1380
    return TSDB_CODE_SUCCESS;
×
1381
  }
1382

1383
  tDecoderClear(&decoder);
148✔
1384

1385
  code = streamMetaAcquireTask(pMeta, req.streamId, req.taskId, &pTask);
150✔
1386
  if (pTask == NULL || (code != 0)) {
149!
1387
    // ignore this code to avoid error code over writing
1388
    if (pMeta->role == NODE_ROLE_LEADER) {
×
1389
      tqError("vgId:%d process consensus checkpointId req:%" PRId64
×
1390
              " transId:%d, failed to acquire task:0x%x, it may have been dropped/stopped already",
1391
              pMeta->vgId, req.checkpointId, req.transId, req.taskId);
1392

1393
      int32_t ret = streamMetaAddFailedTask(pMeta, req.streamId, req.taskId, true);
×
1394
      if (ret) {
×
1395
        tqError("s-task:0x%x failed add check downstream failed, core:%s", req.taskId, tstrerror(ret));
×
1396
      }
1397
    } else {
1398
      tqDebug("vgId:%d task:0x%x stopped in follower node, not set the consensus checkpointId:%" PRId64 " transId:%d",
×
1399
              pMeta->vgId, req.taskId, req.checkpointId, req.transId);
1400
    }
1401

1402
    return 0;
×
1403
  }
1404

1405
  // discard the rsp, since it is expired.
1406
  if (req.startTs < pTask->execInfo.created) {
149!
1407
    tqWarn("s-task:%s vgId:%d createTs:%" PRId64 " recv expired consensus checkpointId:%" PRId64
×
1408
           " from task createTs:%" PRId64 " < task createTs:%" PRId64 ", discard",
1409
           pTask->id.idStr, pMeta->vgId, pTask->execInfo.created, req.checkpointId, req.startTs,
1410
           pTask->execInfo.created);
1411
    if (pMeta->role == NODE_ROLE_LEADER) {
×
1412
      streamMetaAddFailedTaskSelf(pTask, now, true);
×
1413
    }
1414

1415
    streamMetaReleaseTask(pMeta, pTask);
×
1416
    return TSDB_CODE_SUCCESS;
×
1417
  }
1418

1419
  tqDebug("s-task:%s vgId:%d checkpointId:%" PRId64 " restore to consensus-checkpointId:%" PRId64
149✔
1420
          " transId:%d from mnode, reqTs:%" PRId64 " task createTs:%" PRId64,
1421
          pTask->id.idStr, vgId, pTask->chkInfo.checkpointId, req.checkpointId, req.transId, req.startTs,
1422
          pTask->execInfo.created);
1423

1424
  streamMutexLock(&pTask->lock);
149✔
1425
  SConsenChkptInfo* pConsenInfo = &pTask->status.consenChkptInfo;
151✔
1426

1427
  if (pTask->chkInfo.checkpointId < req.checkpointId) {
151✔
1428
    tqFatal("s-task:%s vgId:%d invalid consensus-checkpointId:%" PRId64 ", greater than existed checkpointId:%" PRId64,
1!
1429
            pTask->id.idStr, vgId, req.checkpointId, pTask->chkInfo.checkpointId);
1430

1431
    streamMutexUnlock(&pTask->lock);
1✔
1432
    streamMetaReleaseTask(pMeta, pTask);
×
1433
    return 0;
×
1434
  }
1435

1436
  if (pConsenInfo->consenChkptTransId >= req.transId) {
150!
1437
    tqWarn("s-task:%s vgId:%d latest consensus transId:%d, expired consensus trans:%d, discard", pTask->id.idStr, vgId,
×
1438
            pConsenInfo->consenChkptTransId, req.transId);
1439
    streamMutexUnlock(&pTask->lock);
×
1440
    streamMetaReleaseTask(pMeta, pTask);
×
1441
    return TSDB_CODE_SUCCESS;
×
1442
  }
1443

1444
  if (pTask->chkInfo.checkpointId != req.checkpointId) {
150!
1445
    tqDebug("s-task:%s vgId:%d update the checkpoint from %" PRId64 " to %" PRId64 " transId:%d", pTask->id.idStr, vgId,
×
1446
            pTask->chkInfo.checkpointId, req.checkpointId, req.transId);
1447
    pTask->chkInfo.checkpointId = req.checkpointId;
×
1448
    tqSetRestoreVersionInfo(pTask);
×
1449
  } else {
1450
    tqDebug("s-task:%s vgId:%d consensus-checkpointId:%" PRId64 " equals to current id, transId:%d not update",
150✔
1451
            pTask->id.idStr, vgId, req.checkpointId, req.transId);
1452
  }
1453

1454
  streamTaskSetConsenChkptIdRecv(pTask, req.transId, now);
150✔
1455
  streamMutexUnlock(&pTask->lock);
151✔
1456

1457
  streamMetaWLock(pTask->pMeta);
151✔
1458
  if (pMeta->startInfo.curStage == START_WAIT_FOR_CHKPTID) {
151✔
1459
    pMeta->startInfo.curStage = START_CHECK_DOWNSTREAM;
45✔
1460

1461
    SStartTaskStageInfo info = {.stage = pMeta->startInfo.curStage, .ts = now};
45✔
1462
    taosArrayPush(pMeta->startInfo.pStagesList, &info);
45✔
1463

1464
    tqDebug("vgId:%d wait_for_chkptId stage -> check_down_stream stage, reqTs:%" PRId64 " , numOfStageHist:%d",
45✔
1465
            pMeta->vgId, info.ts, (int32_t)taosArrayGetSize(pMeta->startInfo.pStagesList));
1466
  }
1467

1468
  streamMetaWUnLock(pTask->pMeta);
151✔
1469

1470
  if (pMeta->role == NODE_ROLE_LEADER) {
151!
1471
    code = tqStreamStartOneTaskAsync(pMeta, pTask->pMsgCb, req.streamId, req.taskId);
151✔
1472
    if (code) {
151!
1473
      tqError("s-task:0x%x vgId:%d failed start task async, code:%s", req.taskId, vgId, tstrerror(code));
×
1474
    }
1475
  } else {
1476
    tqDebug("vgId:%d follower not start task:%s", vgId, pTask->id.idStr);
×
1477
  }
1478

1479
  streamMetaReleaseTask(pMeta, pTask);
151✔
1480
  return 0;
150✔
1481
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc