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

taosdata / TDengine / #4870

26 Nov 2025 05:46AM UTC coverage: 64.545% (+0.006%) from 64.539%
#4870

push

travis-ci

guanshengliang
Merge branch '3.0' into cover/3.0

768 of 945 new or added lines in 33 files covered. (81.27%)

2982 existing lines in 119 files now uncovered.

158219 of 245129 relevant lines covered (64.55%)

112474797.36 hits per line

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

75.93
/source/dnode/mnode/impl/src/mndStreamMgmt.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 "mndStream.h"
17
#include "mndDb.h"
18
#include "mndPrivilege.h"
19
#include "mndShow.h"
20
#include "mndStb.h"
21
#include "mndTrans.h"
22
#include "osMemory.h"
23
#include "parser.h"
24
#include "taoserror.h"
25
#include "tmisce.h"
26
#include "tname.h"
27
#include "mndDnode.h"
28
#include "mndVgroup.h"
29
#include "mndSnode.h"
30
#include "mndMnode.h"
31
#include "cmdnodes.h"
32

33
void msmDestroyActionQ() {
848,412✔
34
  SStmQNode* pQNode = NULL;
848,412✔
35

36
  if (NULL == mStreamMgmt.actionQ) {
848,412✔
37
    return;
424,206✔
38
  }
39

40
  while (mndStreamActionDequeue(mStreamMgmt.actionQ, &pQNode)) {
425,888✔
41
  }
42

43
  taosMemoryFreeClear(mStreamMgmt.actionQ->head);
424,206✔
44
  taosMemoryFreeClear(mStreamMgmt.actionQ);
424,206✔
45
}
46

47
void msmDestroySStmThreadCtx(SStmThreadCtx* pCtx) {
2,120,658✔
48
  for (int32_t m = 0; m < STREAM_MAX_GROUP_NUM; ++m) {
12,723,948✔
49
    taosHashCleanup(pCtx->deployStm[m]);
10,603,290✔
50
    taosHashCleanup(pCtx->actionStm[m]);
10,603,290✔
51
  }
52
}
2,120,658✔
53

54
void msmDestroyThreadCtxs() {
848,412✔
55
  if (NULL == mStreamMgmt.tCtx) {
848,412✔
56
    return;
424,206✔
57
  }
58
  
59
  for (int32_t i = 0; i < mStreamMgmt.threadNum; ++i) {
2,544,864✔
60
    msmDestroySStmThreadCtx(mStreamMgmt.tCtx + i);
2,120,658✔
61
  }
62
  taosMemoryFreeClear(mStreamMgmt.tCtx);
424,206✔
63
}
64

65

66
void msmDestroyRuntimeInfo(SMnode *pMnode) {
848,412✔
67
  msmDestroyActionQ();
848,412✔
68
  msmDestroyThreadCtxs();
848,412✔
69

70
  taosHashCleanup(mStreamMgmt.toUpdateScanMap);
848,412✔
71
  mStreamMgmt.toUpdateScanMap = NULL;
848,412✔
72
  mStreamMgmt.toUpdateScanNum = 0;
848,412✔
73
  taosHashCleanup(mStreamMgmt.toDeployVgMap);
848,412✔
74
  mStreamMgmt.toDeployVgMap = NULL;
848,412✔
75
  mStreamMgmt.toDeployVgTaskNum = 0;
848,412✔
76
  taosHashCleanup(mStreamMgmt.toDeploySnodeMap);
848,412✔
77
  mStreamMgmt.toDeploySnodeMap = NULL;
848,412✔
78
  mStreamMgmt.toDeploySnodeTaskNum = 0;
848,412✔
79

80
  taosHashCleanup(mStreamMgmt.dnodeMap);
848,412✔
81
  mStreamMgmt.dnodeMap = NULL;
848,412✔
82
  taosHashCleanup(mStreamMgmt.snodeMap);
848,412✔
83
  mStreamMgmt.snodeMap = NULL;
848,412✔
84
  taosHashCleanup(mStreamMgmt.vgroupMap);
848,412✔
85
  mStreamMgmt.vgroupMap = NULL;
848,412✔
86
  taosHashCleanup(mStreamMgmt.taskMap);
848,412✔
87
  mStreamMgmt.taskMap = NULL;
848,412✔
88
  taosHashCleanup(mStreamMgmt.streamMap);
848,412✔
89
  mStreamMgmt.streamMap = NULL;
848,412✔
90

91
  memset(mStreamMgmt.lastTs, 0, sizeof(mStreamMgmt.lastTs));
848,412✔
92

93
  mstInfo("mnode stream mgmt destroyed");  
848,412✔
94
}
848,412✔
95

96

97
void msmStopStreamByError(int64_t streamId, SStmStatus* pStatus, int32_t errCode, int64_t currTs) {
2,627✔
98
  int32_t code = TSDB_CODE_SUCCESS;
2,627✔
99
  int32_t lino = 0;
2,627✔
100
  SStmStatus* pStream = NULL;
2,627✔
101

102
  mstsInfo("try to stop stream for error: %s", tstrerror(errCode));
2,627✔
103

104
  if (NULL == pStatus) {
2,627✔
105
    pStream = (SStmStatus*)taosHashAcquire(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
2,627✔
106
    if (NULL == pStream) {
2,627✔
107
      mstsInfo("stream already not in streamMap, error:%s", tstrerror(terrno));
×
108
      goto _exit;
×
109
    }
110

111
    pStatus = pStream;
2,627✔
112
  }
113

114
  int8_t stopped = atomic_load_8(&pStatus->stopped);
2,627✔
115
  if (stopped) {
2,627✔
116
    mstsDebug("stream already stopped %d, ignore stop", stopped);
×
117
    goto _exit;
×
118
  }
119

120
  if (pStatus->triggerTask && pStatus->triggerTask->runningStartTs && (currTs - pStatus->triggerTask->runningStartTs) > 2 * MST_ISOLATION_DURATION) {
2,627✔
121
    pStatus->fatalRetryTimes = 0;
372✔
122
    mstsDebug("reset stream retryTimes, running duation:%" PRId64 "ms", currTs - pStatus->triggerTask->runningStartTs);
372✔
123
  }
124

125
  pStatus->fatalRetryTimes++;
2,627✔
126
  pStatus->fatalError = errCode;
2,627✔
127
  pStatus->fatalRetryDuration = (pStatus->fatalRetryTimes > 10) ? MST_MAX_RETRY_DURATION : MST_ISOLATION_DURATION;
2,627✔
128
  pStatus->fatalRetryTs = currTs + pStatus->fatalRetryDuration;
2,627✔
129

130
  pStatus->stat.lastError = errCode;
2,627✔
131
    
132
  if (0 == atomic_val_compare_exchange_8(&pStatus->stopped, 0, 1)) {
2,627✔
133
    MND_STREAM_SET_LAST_TS(STM_EVENT_STM_TERR, currTs);
2,627✔
134
  }
135

136
_exit:
403✔
137

138
  taosHashRelease(mStreamMgmt.streamMap, pStream);
2,627✔
139

140
  if (code) {
2,627✔
141
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
142
  }
143
}
2,627✔
144

145

146
static void msmSetInitRuntimeState(int8_t state) {
424,484✔
147
  switch (state) {
424,484✔
148
    case MND_STM_STATE_WATCH:
278✔
149
      mStreamMgmt.watch.ending = 0;
278✔
150
      mStreamMgmt.watch.taskRemains = 0;
278✔
151
      mStreamMgmt.watch.processing = 0;
278✔
152
      mstInfo("switch to WATCH state");
278✔
153
      break;
278✔
154
    case MND_STM_STATE_NORMAL:
424,206✔
155
      MND_STREAM_SET_LAST_TS(STM_EVENT_NORMAL_BEGIN, taosGetTimestampMs());
847,233✔
156
      mstInfo("switch to NORMAL state");
424,206✔
157
      break;
424,206✔
158
    default:
×
159
      return;
×
160
  }
161
  
162
  atomic_store_8(&mStreamMgmt.state, state);
424,484✔
163
}
164

165
void msmSTDeleteSnodeFromMap(int32_t snodeId) {
×
166
  int32_t code = taosHashRemove(mStreamMgmt.snodeMap, &snodeId, sizeof(snodeId));
×
167
  if (code) {
×
168
    mstWarn("remove snode %d from snodeMap failed, error:%s", snodeId, tstrerror(code));
×
169
  } else {
170
    mstInfo("snode %d removed from snodeMap", snodeId);
×
171
  }
172
}
×
173

174
static int32_t msmSTAddSnodesToMap(SMnode* pMnode) {
458,425✔
175
  int32_t code = TSDB_CODE_SUCCESS;
458,425✔
176
  int32_t lino = 0;
458,425✔
177
  SStmSnodeStatus tasks = {0};
458,425✔
178
  SSnodeObj *pSnode = NULL;
458,425✔
179
  void *pIter = NULL;
458,425✔
180
  while (1) {
181
    pIter = sdbFetch(pMnode->pSdb, SDB_SNODE, pIter, (void **)&pSnode);
521,847✔
182
    if (pIter == NULL) {
521,847✔
183
      break;
458,425✔
184
    }
185

186
    tasks.lastUpTs = taosGetTimestampMs();
63,422✔
187
    code = taosHashPut(mStreamMgmt.snodeMap, &pSnode->id, sizeof(pSnode->id), &tasks, sizeof(tasks));
63,422✔
188
    if (code && TSDB_CODE_DUP_KEY != code) {
63,422✔
189
      sdbRelease(pMnode->pSdb, pSnode);
×
190
      sdbCancelFetch(pMnode->pSdb, pIter);
×
191
      pSnode = NULL;
×
192
      TAOS_CHECK_EXIT(code);
×
193
    }
194

195
    code = TSDB_CODE_SUCCESS;
63,422✔
196
  
197
    sdbRelease(pMnode->pSdb, pSnode);
63,422✔
198
  }
199

200
  pSnode = NULL;
458,425✔
201

202
_exit:
458,425✔
203

204
  if (code) {
458,425✔
205
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
206
  }
207

208
  return code;
458,425✔
209
}
210

211
static int32_t msmSTAddDnodesToMap(SMnode* pMnode) {
966,555✔
212
  int32_t code = TSDB_CODE_SUCCESS;
966,555✔
213
  int32_t lino = 0;
966,555✔
214
  int64_t lastUpTs = INT64_MIN;
966,555✔
215
  SDnodeObj *pDnode = NULL;
966,555✔
216
  void *pIter = NULL;
966,555✔
217
  while (1) {
218
    pIter = sdbFetch(pMnode->pSdb, SDB_DNODE, pIter, (void **)&pDnode);
2,155,213✔
219
    if (pIter == NULL) {
2,155,213✔
220
      break;
966,555✔
221
    }
222

223
    code = taosHashPut(mStreamMgmt.dnodeMap, &pDnode->id, sizeof(pDnode->id), &lastUpTs, sizeof(lastUpTs));
1,188,658✔
224
    if (code && TSDB_CODE_DUP_KEY != code) {
1,188,658✔
225
      sdbRelease(pMnode->pSdb, pDnode);
×
226
      sdbCancelFetch(pMnode->pSdb, pIter);
×
227
      pDnode = NULL;
×
228
      TAOS_CHECK_EXIT(code);
×
229
    }
230

231
    code = TSDB_CODE_SUCCESS;
1,188,658✔
232
    sdbRelease(pMnode->pSdb, pDnode);
1,188,658✔
233
  }
234

235
  pDnode = NULL;
966,555✔
236

237
_exit:
966,555✔
238

239
  if (code) {
966,555✔
240
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
241
  }
242

243
  return code;
966,555✔
244
}
245

246

247

248
static int32_t msmSTAddToTaskMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SList* pList, SStmTaskStatus* pTask) {
1,281,955✔
249
  int32_t code = TSDB_CODE_SUCCESS;
1,281,955✔
250
  int32_t lino = 0;
1,281,955✔
251
  int32_t taskNum = pTask ? 1 : (pList ? MST_LIST_SIZE(pList) : taosArrayGetSize(pTasks));
1,281,955✔
252
  int64_t key[2] = {streamId, 0};
1,281,955✔
253
  SListNode* pNode = pList ? listHead(pList) : NULL;
1,281,955✔
254
  
255
  for (int32_t i = 0; i < taskNum; ++i) {
2,725,402✔
256
    SStmTaskStatus* pStatus = pTask ? pTask : (pList ? (SStmTaskStatus*)pNode->data : taosArrayGet(pTasks, i));
1,443,447✔
257
    key[1] = pStatus->id.taskId;
1,443,447✔
258
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.taskMap, key, sizeof(key), &pStatus, POINTER_BYTES));
1,443,447✔
259
    mstsDebug("task %" PRIx64" tidx %d added to taskMap", pStatus->id.taskId, pStatus->id.taskIdx);
1,443,447✔
260
    if (pNode) {
1,443,447✔
261
      pNode = TD_DLIST_NODE_NEXT(pNode);
282,187✔
262
    }
263
  }
264
  
265
_exit:
1,281,955✔
266

267
  if (code) {
1,281,955✔
268
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
269
  }
270
  
271
  return code;
1,281,955✔
272
}
273

274
static int32_t msmSTAddToVgStreamHash(SHashObj* pHash, int64_t streamId, SStmTaskStatus* pStatus, bool trigReader) {
605,136✔
275
  int32_t code = TSDB_CODE_SUCCESS;
605,136✔
276
  int32_t lino = 0;
605,136✔
277
  SStmVgStreamStatus* pStream = taosHashGet(pHash, &streamId, sizeof(streamId));
605,136✔
278
  if (NULL == pStream) {
605,136✔
279
    SStmVgStreamStatus stream = {0};
462,270✔
280
    if (trigReader) {
462,270✔
281
      stream.trigReaders = taosArrayInit(1, POINTER_BYTES);
294,396✔
282
      TSDB_CHECK_NULL(stream.trigReaders, code, lino, _exit, terrno);
294,396✔
283
      TSDB_CHECK_NULL(taosArrayPush(stream.trigReaders, &pStatus), code, lino, _exit, terrno);
588,792✔
284
    } else {
285
      stream.calcReaders = taosArrayInit(2, POINTER_BYTES);
167,874✔
286
      TSDB_CHECK_NULL(stream.calcReaders, code, lino, _exit, terrno);
167,874✔
287
      TSDB_CHECK_NULL(taosArrayPush(stream.calcReaders, &pStatus), code, lino, _exit, terrno);
335,748✔
288
    }
289
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &stream, sizeof(stream)));
462,270✔
290
    goto _exit;
462,270✔
291
  }
292
  
293
  if (trigReader) {
142,866✔
294
    if (NULL == pStream->trigReaders) {
24,131✔
295
      pStream->trigReaders = taosArrayInit(1, POINTER_BYTES);
24,131✔
296
      TSDB_CHECK_NULL(pStream->trigReaders, code, lino, _exit, terrno);
24,131✔
297
    }
298
    
299
    TSDB_CHECK_NULL(taosArrayPush(pStream->trigReaders, &pStatus), code, lino, _exit, terrno);
48,262✔
300
    goto _exit;
24,131✔
301
  }
302
  
303
  if (NULL == pStream->calcReaders) {
118,735✔
304
    pStream->calcReaders = taosArrayInit(1, POINTER_BYTES);
85,738✔
305
    TSDB_CHECK_NULL(pStream->calcReaders, code, lino, _exit, terrno);
85,738✔
306
  }
307

308
  TSDB_CHECK_NULL(taosArrayPush(pStream->calcReaders, &pStatus), code, lino, _exit, terrno);
237,470✔
309

310
_exit:
118,735✔
311

312
  if (code) {
605,136✔
313
    mstsError("%s task %" PRIx64 " SID:%" PRIx64 " failed to add to vgroup %d streamHash in %s at line %d, error:%s", 
×
314
        trigReader ? "trigReader" : "calcReader", pStatus->id.taskId, pStatus->id.seriousId, pStatus->id.nodeId, __FUNCTION__, lino, tstrerror(code));
315
  } else {
316
    mstsDebug("%s task %" PRIx64 " SID:%" PRIx64 " added to vgroup %d streamHash", 
605,136✔
317
        trigReader ? "trigReader" : "calcReader", pStatus->id.taskId, pStatus->id.seriousId, pStatus->id.nodeId);
318
  }
319

320
  return code;
605,136✔
321
}
322

323
static int32_t msmSTAddToVgroupMapImpl(int64_t streamId, SStmTaskStatus* pStatus, bool trigReader) {
605,136✔
324
  int32_t code = TSDB_CODE_SUCCESS;
605,136✔
325
  int32_t lino = 0;
605,136✔
326
  SStmVgroupStatus vg = {0};
605,136✔
327

328
  SStmVgroupStatus* pVg = taosHashGet(mStreamMgmt.vgroupMap, &pStatus->id.nodeId, sizeof(pStatus->id.nodeId));
605,136✔
329
  if (NULL == pVg) {
605,136✔
330
    vg.streamTasks = taosHashInit(2, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
95,261✔
331
    TSDB_CHECK_NULL(vg.streamTasks, code, lino, _exit, terrno);
95,261✔
332
    taosHashSetFreeFp(vg.streamTasks, mstDestroySStmVgStreamStatus);
95,261✔
333

334
    vg.lastUpTs = taosGetTimestampMs();
95,261✔
335
    TAOS_CHECK_EXIT(msmSTAddToVgStreamHash(vg.streamTasks, streamId, pStatus, trigReader));
95,261✔
336
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.vgroupMap, &pStatus->id.nodeId, sizeof(pStatus->id.nodeId), &vg, sizeof(vg)));
95,261✔
337
  } else {
338
    TAOS_CHECK_EXIT(msmSTAddToVgStreamHash(pVg->streamTasks, streamId, pStatus, trigReader));
509,875✔
339
  }
340
  
341
_exit:
604,575✔
342

343
  if (code) {
605,136✔
344
    mstDestroyVgroupStatus(&vg);
×
345
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
346
  } else {
347
    mstsDebug("task %" PRIx64 " tidx %d added to vgroupMap %d", pStatus->id.taskId, pStatus->id.taskIdx, pStatus->id.nodeId);
605,136✔
348
  }
349

350
  return code;
605,136✔
351
}
352

353
static int32_t msmTDAddToVgroupMap(SHashObj* pVgMap, SStmTaskDeploy* pDeploy, int64_t streamId) {
607,302✔
354
  int32_t code = TSDB_CODE_SUCCESS;
607,302✔
355
  int32_t lino = 0;
607,302✔
356
  SStmVgTasksToDeploy vg = {0};
607,302✔
357
  SStreamTask* pTask = &pDeploy->task;
607,302✔
358
  SStmTaskToDeployExt ext = {0};
607,302✔
359
  ext.deploy = *pDeploy;
607,302✔
360

361
  while (true) {
×
362
    SStmVgTasksToDeploy* pVg = taosHashAcquire(pVgMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId));
607,302✔
363
    if (NULL == pVg) {
607,302✔
364
      vg.taskList = taosArrayInit(20, sizeof(SStmTaskToDeployExt));
130,329✔
365
      TSDB_CHECK_NULL(vg.taskList, code, lino, _return, terrno);
130,329✔
366
      TSDB_CHECK_NULL(taosArrayPush(vg.taskList, &ext), code, lino, _return, terrno);
260,658✔
367
      code = taosHashPut(pVgMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &vg, sizeof(SStmVgTasksToDeploy));
130,329✔
368
      if (TSDB_CODE_SUCCESS == code) {
130,329✔
369
        goto _return;
130,329✔
370
      }
371

372
      if (TSDB_CODE_DUP_KEY != code) {
×
373
        goto _return;
×
374
      }    
375

376
      taosArrayDestroy(vg.taskList);
×
377
      continue;
×
378
    }
379

380
    taosWLockLatch(&pVg->lock);
476,973✔
381
    if (NULL == pVg->taskList) {
476,973✔
382
      pVg->taskList = taosArrayInit(20, sizeof(SStmTaskToDeployExt));
×
383
      TSDB_CHECK_NULL(pVg->taskList, code, lino, _return, terrno);
×
384
    }
385
    if (NULL == taosArrayPush(pVg->taskList, &ext)) {
953,946✔
386
      taosWUnLockLatch(&pVg->lock);
×
387
      TSDB_CHECK_NULL(NULL, code, lino, _return, terrno);
×
388
    }
389
    taosWUnLockLatch(&pVg->lock);
476,973✔
390
    
391
    taosHashRelease(pVgMap, pVg);
476,973✔
392
    break;
476,973✔
393
  }
394
  
395
_return:
607,302✔
396

397
  if (code) {
607,302✔
398
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
399
  } else {
400
    int32_t num = atomic_add_fetch_32(&mStreamMgmt.toDeployVgTaskNum, 1);
607,302✔
401
    msttDebug("task added to toDeployVgTaskNum, vgToDeployTaskNum:%d", num);
607,302✔
402
  }
403

404
  return code;
607,302✔
405
}
406

407

408
static int32_t msmSTAddToSnodeStreamHash(SHashObj* pHash, int64_t streamId, SStmTaskStatus* pStatus, int32_t deployId) {
839,163✔
409
  int32_t code = TSDB_CODE_SUCCESS;
839,163✔
410
  int32_t lino = 0;
839,163✔
411
  SStmSnodeStreamStatus* pStream = taosHashGet(pHash, &streamId, sizeof(streamId));
839,163✔
412
  if (NULL == pStream) {
839,163✔
413
    SStmSnodeStreamStatus stream = {0};
214,455✔
414
    if (deployId < 0) {
214,455✔
415
      stream.trigger = pStatus;
3,513✔
416
    } else {
417
      stream.runners[deployId] = taosArrayInit(2, POINTER_BYTES);
210,942✔
418
      TSDB_CHECK_NULL(stream.runners[deployId], code, lino, _exit, terrno);
210,942✔
419
      TSDB_CHECK_NULL(taosArrayPush(stream.runners[deployId], &pStatus), code, lino, _exit, terrno);
421,884✔
420
    }
421
    
422
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &stream, sizeof(stream)));
214,455✔
423
    goto _exit;
214,455✔
424
  }
425
  
426
  if (deployId < 0) {
624,708✔
427
    if (NULL != pStream->trigger) {
200,184✔
428
      mstsWarn("stream already got trigger task %" PRIx64 " SID:%" PRIx64 " in snode %d, replace it with task %" PRIx64 " SID:%" PRIx64, 
×
429
          pStream->trigger->id.taskId, pStream->trigger->id.seriousId, pStatus->id.nodeId, pStatus->id.taskId, pStatus->id.seriousId);
430
    }
431
    
432
    pStream->trigger = pStatus;
200,184✔
433
    goto _exit;
200,184✔
434
  }
435
  
436
  if (NULL == pStream->runners[deployId]) {
424,524✔
437
    pStream->runners[deployId] = taosArrayInit(2, POINTER_BYTES);
390,462✔
438
    TSDB_CHECK_NULL(pStream->runners[deployId], code, lino, _exit, terrno);
390,462✔
439
  }
440

441
  TSDB_CHECK_NULL(taosArrayPush(pStream->runners[deployId], &pStatus), code, lino, _exit, terrno);
849,048✔
442

443
_exit:
424,524✔
444

445
  if (code) {
839,163✔
446
    mstsError("%s task %" PRIx64 " SID:%" PRIx64 " failed to add to snode %d streamHash deployId:%d in %s at line %d, error:%s", 
×
447
        (deployId < 0) ? "trigger" : "runner", pStatus->id.taskId, pStatus->id.seriousId, pStatus->id.nodeId, deployId, __FUNCTION__, lino, tstrerror(code));
448
  } else {
449
    mstsDebug("%s task %" PRIx64 " SID:%" PRIx64 " added to snode %d streamHash deployId:%d", 
839,163✔
450
        (deployId < 0) ? "trigger" : "runner", pStatus->id.taskId, pStatus->id.seriousId, pStatus->id.nodeId, deployId);
451
  }
452

453
  return code;
839,163✔
454
}
455

456

457
static int32_t msmSTAddToSnodeMapImpl(int64_t streamId, SStmTaskStatus* pStatus, int32_t deployId) {
839,163✔
458
  int32_t code = TSDB_CODE_SUCCESS;
839,163✔
459
  int32_t lino = 0;
839,163✔
460

461
  SStmSnodeStatus* pSnode = taosHashGet(mStreamMgmt.snodeMap, &pStatus->id.nodeId, sizeof(pStatus->id.nodeId));
839,163✔
462
  if (NULL == pSnode) {
839,163✔
463
    mstsWarn("snode %d not exists in snodeMap anymore, may be dropped", pStatus->id.nodeId);
×
464
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
465
  } else {
466
    if (NULL == pSnode->streamTasks) {
839,163✔
467
      pSnode->streamTasks = taosHashInit(2, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
27,714✔
468
      TSDB_CHECK_NULL(pSnode->streamTasks, code, lino, _exit, terrno);
27,714✔
469
      taosHashSetFreeFp(pSnode->streamTasks, mstDestroySStmSnodeStreamStatus);
27,714✔
470
    }
471
    
472
    TAOS_CHECK_EXIT(msmSTAddToSnodeStreamHash(pSnode->streamTasks, streamId, pStatus, deployId));
839,163✔
473
  }
474
  
475
_exit:
839,163✔
476

477
  if (code) {
839,163✔
478
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
479
  } else {
480
    mstsDebug("%s task %" PRIx64 " tidx %d added to snodeMap, snodeId:%d", (deployId < 0) ? "trigger" : "runner", 
839,163✔
481
        pStatus->id.taskId, pStatus->id.taskIdx, pStatus->id.nodeId);
482
  }
483

484
  return code;
839,163✔
485
}
486

487

488

489
static int32_t msmTDAddTriggerToSnodeMap(SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
203,697✔
490
  int32_t code = TSDB_CODE_SUCCESS;
203,697✔
491
  int32_t lino = 0;
203,697✔
492
  int64_t streamId = pStream->pCreate->streamId;
203,697✔
493
  SStmSnodeTasksDeploy snode = {0};
203,697✔
494
  SStmTaskToDeployExt ext;
200,331✔
495
  SStreamTask* pTask = &pDeploy->task;
203,697✔
496

497
  while (true) {
×
498
    SStmSnodeTasksDeploy* pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId));
203,697✔
499
    if (NULL == pSnode) {
203,697✔
500
      snode.triggerList = taosArrayInit(10, sizeof(SStmTaskToDeployExt));
397✔
501
      TSDB_CHECK_NULL(snode.triggerList, code, lino, _return, terrno);
397✔
502

503
      ext.deploy = *pDeploy;
397✔
504
      ext.deployed = false;
397✔
505
      TSDB_CHECK_NULL(taosArrayPush(snode.triggerList, &ext), code, lino, _return, terrno);
794✔
506

507
      code = taosHashPut(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &snode, sizeof(snode));
397✔
508
      if (TSDB_CODE_SUCCESS == code) {
397✔
509
        goto _return;
397✔
510
      }
511

512
      if (TSDB_CODE_DUP_KEY != code) {
×
513
        goto _return;
×
514
      }    
515

516
      taosArrayDestroy(snode.triggerList);
×
517
      continue;
×
518
    }
519
    
520
    taosWLockLatch(&pSnode->lock);
203,300✔
521
    if (NULL == pSnode->triggerList) {
203,300✔
522
      pSnode->triggerList = taosArrayInit(10, sizeof(SStmTaskToDeployExt));
46,213✔
523
      if (NULL == pSnode->triggerList) {
46,213✔
524
        taosWUnLockLatch(&pSnode->lock);
×
525
        TSDB_CHECK_NULL(pSnode->triggerList, code, lino, _return, terrno);
×
526
      }
527
    }
528
    
529
    ext.deploy = *pDeploy;
203,300✔
530
    ext.deployed = false;
203,300✔
531
    
532
    if (NULL == taosArrayPush(pSnode->triggerList, &ext)) {
406,600✔
533
      taosWUnLockLatch(&pSnode->lock);
×
534
      TSDB_CHECK_NULL(NULL, code, lino, _return, terrno);
×
535
    }
536
    taosWUnLockLatch(&pSnode->lock);
203,300✔
537
    
538
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
203,300✔
539
    break;
203,300✔
540
  }
541
  
542
_return:
203,697✔
543

544
  if (code) {
203,697✔
545
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
546
  } else {
547
    msttDebug("trigger task added to toDeploySnodeMap, tidx:%d", pTask->taskIdx);
203,697✔
548
  }
549

550
  return code;
203,697✔
551
}
552

553
static int32_t msmTDAddRunnerToSnodeMap(SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
635,466✔
554
  int32_t code = TSDB_CODE_SUCCESS;
635,466✔
555
  int32_t lino = 0;
635,466✔
556
  int64_t streamId = pStream->pCreate->streamId;
635,466✔
557
  SStmSnodeTasksDeploy snode = {0};
635,466✔
558
  SStmTaskToDeployExt ext;
625,368✔
559
  SStreamTask* pTask = &pDeploy->task;
635,466✔
560

561
  while (true) {
×
562
    SStmSnodeTasksDeploy* pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId));
635,466✔
563
    if (NULL == pSnode) {
635,466✔
564
      snode.runnerList = taosArrayInit(10, sizeof(SStmTaskToDeployExt));
50,018✔
565
      TSDB_CHECK_NULL(snode.runnerList, code, lino, _return, terrno);
50,018✔
566

567
      ext.deploy = *pDeploy;
50,018✔
568
      ext.deployed = false;
50,018✔
569
      TSDB_CHECK_NULL(taosArrayPush(snode.runnerList, &ext), code, lino, _return, terrno);
100,036✔
570

571
      code = taosHashPut(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &snode, sizeof(snode));
50,018✔
572
      if (TSDB_CODE_SUCCESS == code) {
50,018✔
573
        goto _return;
50,018✔
574
      }
575

576
      if (TSDB_CODE_DUP_KEY != code) {
×
577
        goto _return;
×
578
      }    
579

580
      taosArrayDestroy(snode.runnerList);
×
581
      continue;
×
582
    }
583
    
584
    taosWLockLatch(&pSnode->lock);
585,448✔
585
    if (NULL == pSnode->runnerList) {
585,448✔
586
      pSnode->runnerList = taosArrayInit(10, sizeof(SStmTaskToDeployExt));
397✔
587
      if (NULL == pSnode->runnerList) {
397✔
588
        taosWUnLockLatch(&pSnode->lock);
×
589
        TSDB_CHECK_NULL(pSnode->runnerList, code, lino, _return, terrno);
×
590
      }
591
    }
592
    
593
    ext.deploy = *pDeploy;
585,448✔
594
    ext.deployed = false;
585,448✔
595
    
596
    if (NULL == taosArrayPush(pSnode->runnerList, &ext)) {
1,170,896✔
597
      taosWUnLockLatch(&pSnode->lock);
×
598
      TSDB_CHECK_NULL(NULL, code, lino, _return, terrno);
×
599
    }
600
    taosWUnLockLatch(&pSnode->lock);
585,448✔
601
    
602
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
585,448✔
603
    break;
585,448✔
604
  }
605
  
606
_return:
635,466✔
607

608
  if (code) {
635,466✔
609
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
610
  } else {
611
    msttDebug("task added to toDeploySnodeMap, tidx:%d", pTask->taskIdx);
635,466✔
612
  }
613

614
  return code;
635,466✔
615
}
616

617
static int32_t msmTDAddRunnersToSnodeMap(SArray* runnerList, SStreamObj* pStream) {
601,404✔
618
  int32_t code = TSDB_CODE_SUCCESS;
601,404✔
619
  int32_t lino = 0;
601,404✔
620
  int32_t runnerNum = taosArrayGetSize(runnerList);
601,404✔
621
  SStmTaskDeploy* pDeploy = NULL;
601,404✔
622
  int64_t streamId = pStream->pCreate->streamId;
601,404✔
623

624
  for (int32_t i = 0; i < runnerNum; ++i) {
1,236,870✔
625
    pDeploy = taosArrayGet(runnerList, i);
635,466✔
626
    
627
    TAOS_CHECK_EXIT(msmTDAddRunnerToSnodeMap(pDeploy, pStream));
635,466✔
628
    
629
    (void)atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);    
635,466✔
630
  }
631

632
_exit:
601,404✔
633

634
  if (code) {
601,404✔
635
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
636
  }
637

638
  return code;
601,404✔
639
}
640

641

642
int32_t msmUpdateSnodeUpTs(SStmGrpCtx* pCtx) {
1,460,743✔
643
  int32_t  code = TSDB_CODE_SUCCESS;
1,460,743✔
644
  int32_t  lino = 0;
1,460,743✔
645
  SStmSnodeStatus* pStatus = NULL;
1,460,743✔
646
  bool     noExists = false;
1,460,743✔
647

648
  while (true) {
649
    pStatus = taosHashGet(mStreamMgmt.snodeMap, &pCtx->pReq->snodeId, sizeof(pCtx->pReq->snodeId));
1,479,873✔
650
    if (NULL == pStatus) {
1,479,873✔
651
      if (noExists) {
19,527✔
652
        mstWarn("snode %d not exists in snodeMap, may be dropped, ignore it", pCtx->pReq->snodeId);
397✔
653
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NODE_NOT_EXISTS);
397✔
654
      }
655

656
      noExists = true;
19,130✔
657
      TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pCtx->pMnode));
19,130✔
658
      
659
      continue;
19,130✔
660
    }
661

662
    atomic_store_32(&pStatus->runnerThreadNum, pCtx->pReq->runnerThreadNum);
1,460,346✔
663
    
664
    while (true) {
×
665
      int64_t lastTsValue = atomic_load_64(&pStatus->lastUpTs);
1,460,346✔
666
      if (pCtx->currTs > lastTsValue) {
1,460,346✔
667
        if (lastTsValue == atomic_val_compare_exchange_64(&pStatus->lastUpTs, lastTsValue, pCtx->currTs)) {
1,441,613✔
668
          mstDebug("snode %d lastUpTs updated", pCtx->pReq->snodeId);
1,441,613✔
669
          return code;
1,441,613✔
670
        }
671

672
        continue;
×
673
      }
674

675
      return code;
18,733✔
676
    }
677

678
    break;
679
  }
680

681
_exit:
397✔
682

683
  if (code) {
397✔
684
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
397✔
685
  }
686

687
  return code;  
397✔
688
}
689

690
void msmUpdateVgroupUpTs(SStmGrpCtx* pCtx, int32_t vgId) {
41,598,891✔
691
  int32_t  code = TSDB_CODE_SUCCESS;
41,598,891✔
692
  int32_t  lino = 0;
41,598,891✔
693
  SStmVgroupStatus* pStatus = taosHashGet(mStreamMgmt.vgroupMap, &vgId, sizeof(vgId));
41,598,891✔
694
  if (NULL == pStatus) {
41,598,891✔
695
    mstDebug("vgroup %d not exists in vgroupMap, ignore update upTs", vgId);
36,139,626✔
696
    return;
36,139,626✔
697
  }
698

699
  while (true) {
×
700
    int64_t lastTsValue = atomic_load_64(&pStatus->lastUpTs);
5,459,265✔
701
    if (pCtx->currTs > lastTsValue) {
5,459,265✔
702
      if (lastTsValue == atomic_val_compare_exchange_64(&pStatus->lastUpTs, lastTsValue, pCtx->currTs)) {
5,366,064✔
703
        mstDebug("vgroup %d lastUpTs updated to %" PRId64, vgId, pCtx->currTs);
5,366,064✔
704
        return;
5,366,064✔
705
      }
706

707
      continue;
×
708
    }
709

710
    return;
93,201✔
711
  }  
712
}
713

714
int32_t msmUpdateVgroupsUpTs(SStmGrpCtx* pCtx) {
15,038,858✔
715
  int32_t code = TSDB_CODE_SUCCESS;
15,038,858✔
716
  int32_t lino = 0;
15,038,858✔
717
  int32_t vgNum = taosArrayGetSize(pCtx->pReq->pVgLeaders);
15,038,858✔
718

719
  mstDebug("start to update vgroups upTs");
15,038,858✔
720
  
721
  for (int32_t i = 0; i < vgNum; ++i) {
56,273,306✔
722
    int32_t* vgId = taosArrayGet(pCtx->pReq->pVgLeaders, i);
41,234,448✔
723

724
    msmUpdateVgroupUpTs(pCtx, *vgId);
41,234,448✔
725
  }
726

727
_exit:
15,038,858✔
728

729
  if (code) {
15,038,858✔
730
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
731
  }
732

733
  return code;
15,038,858✔
734
}
735

736

737

738
void* msmSearchCalcCacheScanPlan(SArray* pList) {
394,276✔
739
  int32_t num = taosArrayGetSize(pList);
394,276✔
740
  for (int32_t i = 0; i < num; ++i) {
1,046,236✔
741
    SStreamCalcScan* pScan = taosArrayGet(pList, i);
869,699✔
742
    if (pScan->readFromCache) {
869,699✔
743
      return pScan->scanPlan;
217,739✔
744
    }
745
  }
746

747
  return NULL;
176,537✔
748
}
749

750
int32_t msmBuildReaderDeployInfo(SStmTaskDeploy* pDeploy, void* calcScanPlan, SStmStatus* pInfo, bool triggerReader) {
607,302✔
751
  SStreamReaderDeployMsg* pMsg = &pDeploy->msg.reader;
607,302✔
752
  pMsg->triggerReader = triggerReader;
607,302✔
753
  
754
  if (triggerReader) {
607,302✔
755
    SStreamReaderDeployFromTrigger* pTrigger = &pMsg->msg.trigger;
319,610✔
756
    pTrigger->triggerTblName = pInfo->pCreate->triggerTblName;
319,610✔
757
    pTrigger->triggerTblUid = pInfo->pCreate->triggerTblUid;
319,610✔
758
    pTrigger->triggerTblSuid = pInfo->pCreate->triggerTblSuid;
319,610✔
759
    pTrigger->triggerTblType = pInfo->pCreate->triggerTblType;
319,610✔
760
    pTrigger->isTriggerTblVirt = STREAM_IS_VIRTUAL_TABLE(pInfo->pCreate->triggerTblType, pInfo->pCreate->flags);
319,610✔
761
    pTrigger->deleteReCalc = pInfo->pCreate->deleteReCalc;
319,610✔
762
    pTrigger->deleteOutTbl = pInfo->pCreate->deleteOutTbl;
319,610✔
763
    pTrigger->partitionCols = pInfo->pCreate->partitionCols;
319,610✔
764
    pTrigger->triggerCols = pInfo->pCreate->triggerCols;
319,610✔
765
    //pTrigger->triggerPrevFilter = pStream->pCreate->triggerPrevFilter;
766
    pTrigger->triggerScanPlan = pInfo->pCreate->triggerScanPlan;
319,610✔
767
    pTrigger->calcCacheScanPlan = msmSearchCalcCacheScanPlan(pInfo->pCreate->calcScanPlanList);
319,610✔
768
  } else {
769
    SStreamReaderDeployFromCalc* pCalc = &pMsg->msg.calc;
287,692✔
770
    pCalc->execReplica = pInfo->runnerDeploys * pInfo->runnerReplica;
287,692✔
771
    pCalc->calcScanPlan = calcScanPlan;
287,692✔
772
  }
773

774
  return TSDB_CODE_SUCCESS;
607,302✔
775
}
776

777
int32_t msmBuildTriggerRunnerTargets(SMnode* pMnode, SStmStatus* pInfo, int64_t streamId, SArray** ppRes) {
200,184✔
778
  int32_t code = TSDB_CODE_SUCCESS;
200,184✔
779
  int32_t lino = 0;
200,184✔
780

781
  if (pInfo->runnerDeploys > 0) {
200,184✔
782
    *ppRes = taosArrayInit(pInfo->runnerDeploys, sizeof(SStreamRunnerTarget));
200,184✔
783
    TSDB_CHECK_NULL(*ppRes, code, lino, _exit, terrno);
200,184✔
784
  }
785
  
786
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
800,736✔
787
    SStmTaskStatus* pStatus = taosArrayGetLast(pInfo->runners[i]);
600,552✔
788
    TSDB_CHECK_NULL(pStatus, code, lino, _exit, terrno);
600,552✔
789

790
    if (!STREAM_IS_TOP_RUNNER(pStatus->flags)) {
600,552✔
UNCOV
791
      mstsError("the last runner task %" PRIx64 " SID:%" PRId64 " tidx:%d in deploy %d is not top runner", 
×
792
          pStatus->id.taskId, pStatus->id.seriousId, pStatus->id.taskIdx, i);
UNCOV
793
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
794
    }
795
    
796
    SStreamRunnerTarget runner;
590,454✔
797
    runner.addr.taskId = pStatus->id.taskId;
600,552✔
798
    runner.addr.nodeId = pStatus->id.nodeId;
600,552✔
799
    runner.addr.epset = mndGetDnodeEpsetById(pMnode, pStatus->id.nodeId);
600,552✔
800
    runner.execReplica = pInfo->runnerReplica; 
600,552✔
801
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &runner), code, lino, _exit, terrno);
1,201,104✔
802
    mstsDebug("the %dth runner target added to trigger's runnerList, TASK:%" PRIx64 , i, runner.addr.taskId);
600,552✔
803
  }
804

805
_exit:
200,184✔
806

807
  if (code) {
200,184✔
UNCOV
808
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
809
  }
810
  
811
  return TSDB_CODE_SUCCESS;
200,184✔
812
}
813

UNCOV
814
int32_t msmBuildStreamSnodeInfo(SMnode* pMnode, SStreamObj* pStream, SStreamSnodeInfo* pInfo) {
×
815
  int64_t streamId = pStream->pCreate->streamId;
×
816
  int32_t leaderSnodeId = atomic_load_32(&pStream->mainSnodeId);
×
817
  SSnodeObj* pSnode = mndAcquireSnode(pMnode, leaderSnodeId);
×
818
  if (NULL == pSnode) {
×
819
    mstsError("snode %d not longer exists, ignore build stream snode info", leaderSnodeId);
×
820
    return TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
821
  }
822
  
UNCOV
823
  pInfo->leaderSnodeId = leaderSnodeId;
×
824
  pInfo->replicaSnodeId = pSnode->replicaId;
×
825

UNCOV
826
  mndReleaseSnode(pMnode, pSnode);
×
827

UNCOV
828
  pInfo->leaderEpSet = mndGetDnodeEpsetById(pMnode, pInfo->leaderSnodeId);
×
829
  if (GOT_SNODE(pInfo->replicaSnodeId)) {
×
830
    pInfo->replicaEpSet = mndGetDnodeEpsetById(pMnode, pInfo->replicaSnodeId);
×
831
  }
832

UNCOV
833
  return TSDB_CODE_SUCCESS;
×
834
}
835

836
int32_t msmBuildTriggerDeployInfo(SMnode* pMnode, SStmStatus* pInfo, SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
203,697✔
837
  int32_t code = TSDB_CODE_SUCCESS;
203,697✔
838
  int32_t lino = 0;
203,697✔
839
  int64_t streamId = pStream->pCreate->streamId;
203,697✔
840
  SStreamTriggerDeployMsg* pMsg = &pDeploy->msg.trigger;
203,697✔
841
  
842
  pMsg->triggerType = pStream->pCreate->triggerType;
203,697✔
843
  pMsg->igDisorder = pStream->pCreate->igDisorder;
203,697✔
844
  pMsg->fillHistory = pStream->pCreate->fillHistory;
203,697✔
845
  pMsg->fillHistoryFirst = pStream->pCreate->fillHistoryFirst;
203,697✔
846
  pMsg->lowLatencyCalc = pStream->pCreate->lowLatencyCalc;
203,697✔
847
  pMsg->igNoDataTrigger = pStream->pCreate->igNoDataTrigger;
203,697✔
848
  pMsg->isTriggerTblVirt = STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags);
203,697✔
849
  pMsg->triggerHasPF = pStream->pCreate->triggerHasPF;
203,697✔
850
  pMsg->isTriggerTblStb = (pStream->pCreate->triggerTblType == TSDB_SUPER_TABLE);
203,697✔
851
  pMsg->precision = pStream->pCreate->triggerPrec;
203,697✔
852
  pMsg->partitionCols = pStream->pCreate->partitionCols;
203,697✔
853

854
  pMsg->pNotifyAddrUrls = pInfo->pCreate->pNotifyAddrUrls;
203,697✔
855
  pMsg->notifyEventTypes = pStream->pCreate->notifyEventTypes;
203,697✔
856
  pMsg->addOptions = pStream->pCreate->addOptions;
203,697✔
857
  pMsg->notifyHistory = pStream->pCreate->notifyHistory;
203,697✔
858

859
  pMsg->maxDelay = pStream->pCreate->maxDelay;
203,697✔
860
  pMsg->fillHistoryStartTime = pStream->pCreate->fillHistoryStartTime;
203,697✔
861
  pMsg->watermark = pStream->pCreate->watermark;
203,697✔
862
  pMsg->expiredTime = pStream->pCreate->expiredTime;
203,697✔
863
  pMsg->trigger = pInfo->pCreate->trigger;
203,697✔
864

865
  pMsg->eventTypes = pStream->pCreate->eventTypes;
203,697✔
866
  pMsg->placeHolderBitmap = pStream->pCreate->placeHolderBitmap;
203,697✔
867
  pMsg->calcTsSlotId = pStream->pCreate->calcTsSlotId;
203,697✔
868
  pMsg->triTsSlotId = pStream->pCreate->triTsSlotId;
203,697✔
869
  pMsg->triggerPrevFilter = pInfo->pCreate->triggerPrevFilter;
203,697✔
870
  if (STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags)) {
203,697✔
871
    pMsg->triggerScanPlan = pInfo->pCreate->triggerScanPlan;
74,666✔
872
    pMsg->calcCacheScanPlan = msmSearchCalcCacheScanPlan(pInfo->pCreate->calcScanPlanList);
74,666✔
873
  }
874

875
  SStreamTaskAddr addr;
200,331✔
876
  int32_t triggerReaderNum = taosArrayGetSize(pInfo->trigReaders);
203,697✔
877
  if (triggerReaderNum > 0) {
203,697✔
878
    pMsg->readerList = taosArrayInit(triggerReaderNum, sizeof(SStreamTaskAddr));
202,504✔
879
    TSDB_CHECK_NULL(pMsg->readerList, code, lino, _exit, terrno);
202,504✔
880
  }
881
  
882
  for (int32_t i = 0; i < triggerReaderNum; ++i) {
456,334✔
883
    SStmTaskStatus* pStatus = taosArrayGet(pInfo->trigReaders, i);
252,637✔
884
    addr.taskId = pStatus->id.taskId;
252,637✔
885
    addr.nodeId = pStatus->id.nodeId;
252,637✔
886
    addr.epset = mndGetVgroupEpsetById(pMnode, pStatus->id.nodeId);
252,637✔
887
    TSDB_CHECK_NULL(taosArrayPush(pMsg->readerList, &addr), code, lino, _exit, terrno);
505,274✔
888
    mstsDebug("the %dth trigReader src added to trigger's readerList, TASK:%" PRIx64 " nodeId:%d", i, addr.taskId, addr.nodeId);
252,637✔
889
  }
890

891
  pMsg->leaderSnodeId = pStream->mainSnodeId;
203,697✔
892
  pMsg->streamName = pInfo->streamName;
203,697✔
893

894
  if (0 == pInfo->runnerNum) {
203,697✔
895
    mstsDebug("no runner task, skip set trigger's runner list, deployNum:%d", pInfo->runnerDeploys);
3,513✔
896
    return code;
3,513✔
897
  }
898

899
  TAOS_CHECK_EXIT(msmBuildTriggerRunnerTargets(pMnode, pInfo, streamId, &pMsg->runnerList));
200,184✔
900

901
_exit:
200,184✔
902

903
  if (code) {
200,184✔
UNCOV
904
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
905
  } else {
906
    mstsDebug("trigger deploy info built, readerNum:%d, runnerNum:%d", (int32_t)taosArrayGetSize(pMsg->readerList), (int32_t)taosArrayGetSize(pMsg->runnerList));
200,184✔
907
  }
908
  
909
  return TSDB_CODE_SUCCESS;
200,184✔
910
}
911

912

913
int32_t msmBuildRunnerDeployInfo(SStmTaskDeploy* pDeploy, SSubplan *plan, SStreamObj* pStream, SStmStatus* pInfo, bool topPlan) {
635,466✔
914
  int32_t code = TSDB_CODE_SUCCESS;
635,466✔
915
  int32_t lino = 0;
635,466✔
916
  int64_t streamId = pStream->pCreate->streamId;
635,466✔
917
  SStreamRunnerDeployMsg* pMsg = &pDeploy->msg.runner;
635,466✔
918
  //TAOS_CHECK_EXIT(qSubPlanToString(plan, &pMsg->pPlan, NULL));
919

920
  pMsg->execReplica = pInfo->runnerReplica;
635,466✔
921
  pMsg->streamName = pInfo->streamName;
635,466✔
922
  //TAOS_CHECK_EXIT(nodesCloneNode((SNode*)plan, (SNode**)&pMsg->pPlan));
923
  pMsg->pPlan = plan;
635,466✔
924
  pMsg->outDBFName = pInfo->pCreate->outDB;
635,466✔
925
  pMsg->outTblName = pInfo->pCreate->outTblName;
635,466✔
926
  pMsg->outTblType = pStream->pCreate->outTblType;
635,466✔
927
  pMsg->lowLatencyCalc = pStream->pCreate->lowLatencyCalc;
635,466✔
928
  pMsg->calcNotifyOnly = pStream->pCreate->calcNotifyOnly;
635,466✔
929
  pMsg->topPlan = topPlan;
635,466✔
930
  pMsg->pNotifyAddrUrls = pInfo->pCreate->pNotifyAddrUrls;
635,466✔
931
  pMsg->addOptions = pStream->pCreate->addOptions;
635,466✔
932
  if(pStream->pCreate->trigger.sliding.overlap) {
635,466✔
933
    pMsg->addOptions |= CALC_SLIDING_OVERLAP;
14,073✔
934
  }
935
  pMsg->outCols = pInfo->pCreate->outCols;
635,466✔
936
  pMsg->outTags = pInfo->pCreate->outTags;
635,466✔
937
  pMsg->outStbUid = pStream->pCreate->outStbUid;
635,466✔
938
  pMsg->outStbSversion = pStream->pCreate->outStbSversion;
635,466✔
939
  
940
  pMsg->subTblNameExpr = pInfo->pCreate->subTblNameExpr;
635,466✔
941
  pMsg->tagValueExpr = pInfo->pCreate->tagValueExpr;
635,466✔
942
  pMsg->forceOutCols = pInfo->pCreate->forceOutCols;
635,466✔
943

944
_exit:
635,466✔
945

946
  if (code) {
635,466✔
UNCOV
947
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
948
  }
949
  
950
  return code;
635,466✔
951
}
952

953

954
static int32_t msmSTAddToVgroupMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SList* pList, SStmTaskStatus* pTask, bool trigReader) {
477,706✔
955
  int32_t code = TSDB_CODE_SUCCESS;
477,706✔
956
  int32_t lino = 0;
477,706✔
957
  int32_t taskNum = pTask ? 1 : (pList ? MST_LIST_SIZE(pList) :taosArrayGetSize(pTasks));
477,706✔
958
  SListNode* pNode = pList ? listHead(pList) : NULL;
477,706✔
959
  
960
  for (int32_t i = 0; i < taskNum; ++i) {
1,082,842✔
961
    SStmTaskStatus* pStatus = pTask ? pTask : (pNode ? (SStmTaskStatus*)pNode->data : taosArrayGet(pTasks, i));
605,136✔
962
    TAOS_CHECK_EXIT(msmSTAddToVgroupMapImpl(streamId, pStatus, trigReader));
605,136✔
963
    if (pNode) {
605,136✔
964
      pNode = TD_DLIST_NODE_NEXT(pNode);
282,187✔
965
    }
966
  }
967
  
968
_exit:
477,706✔
969

970
  if (code) {
477,706✔
UNCOV
971
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
972
  }
973
  
974
  return code;
477,706✔
975
}
976

977

978
static int32_t msmSTAddToSnodeMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SStmTaskStatus* pTask, int32_t taskNum, int32_t deployId) {
805,101✔
979
  int32_t code = TSDB_CODE_SUCCESS;
805,101✔
980
  int32_t lino = 0;
805,101✔
981
  int32_t rtaskNum = (taskNum > 0) ? taskNum : taosArrayGetSize(pTasks);
805,101✔
982
  int32_t taskType = (deployId < 0) ? STREAM_TRIGGER_TASK : STREAM_RUNNER_TASK;
805,101✔
983
  
984
  for (int32_t i = 0; i < rtaskNum; ++i) {
1,644,264✔
985
    SStmTaskStatus* pStatus = (taskNum > 0) ? (pTask + i) : taosArrayGet(pTasks, i);
839,163✔
986
    TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pStatus, deployId));
839,163✔
987
  }
988
  
989
_exit:
805,101✔
990

991
  if (code) {
805,101✔
UNCOV
992
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
993
  }
994

995
  return code;
805,101✔
996
}
997

998
int64_t msmAssignTaskId(void) {
1,443,447✔
999
  return atomic_fetch_add_64(&mStreamMgmt.lastTaskId, 1);
1,443,447✔
1000
}
1001

1002
int64_t msmAssignTaskSeriousId(void) {
1,443,447✔
1003
  return taosGetTimestampNs();
1,443,447✔
1004
}
1005

1006

1007
int32_t msmIsSnodeAlive(SMnode* pMnode, int32_t snodeId, int64_t streamId, bool* alive) {
1,061,358✔
1008
  int32_t code = TSDB_CODE_SUCCESS;
1,061,358✔
1009
  int32_t lino = 0;
1,061,358✔
1010
  bool     noExists = false;
1,061,358✔
1011
  SStmSnodeStatus* pStatus = NULL;
1,061,358✔
1012

1013
  while (true) {
1014
    pStatus = taosHashGet(mStreamMgmt.snodeMap, &snodeId, sizeof(snodeId));
1,070,938✔
1015
    if (NULL == pStatus) {
1,070,938✔
1016
      if (noExists) {
9,580✔
UNCOV
1017
        mstsError("snode %d not exists in snodeMap", snodeId);
×
1018
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1019
      }
1020

1021
      noExists = true;
9,580✔
1022
      TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pMnode));
9,580✔
1023
      
1024
      continue;
9,580✔
1025
    }
1026

1027
    *alive = (pStatus->runnerThreadNum >= 0);
1,061,358✔
1028
    break;
1,061,358✔
1029
  }
1030

1031
_exit:
1,061,358✔
1032

1033
  if (code) {
1,061,358✔
UNCOV
1034
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1035
  }
1036

1037
  return code;
1,061,358✔
1038
}
1039

1040
int32_t msmRetrieveStaticSnodeId(SMnode* pMnode, SStreamObj* pStream) {
404,307✔
1041
  int32_t code = TSDB_CODE_SUCCESS;
404,307✔
1042
  int32_t lino = 0;
404,307✔
1043
  bool alive = false;
404,307✔
1044
  int32_t mainSnodeId = atomic_load_32(&pStream->mainSnodeId);
404,307✔
1045
  int32_t snodeId = mainSnodeId;
404,307✔
1046
  int64_t streamId = pStream->pCreate->streamId;
404,307✔
1047
  
1048
  while (true) {
1049
    TAOS_CHECK_EXIT(msmIsSnodeAlive(pMnode, snodeId, streamId, &alive));
404,307✔
1050

1051
    if (alive) {
404,307✔
1052
      return snodeId;
404,307✔
1053
    }
1054
    
UNCOV
1055
    if (snodeId == mainSnodeId) {
×
1056
      SSnodeObj* pSnode = mndAcquireSnode(pMnode, snodeId);
×
1057
      if (NULL == pSnode) {
×
1058
        stsWarn("snode %d not longer exists, ignore assign snode", snodeId);
×
1059
        return 0;
×
1060
      }
1061
      
UNCOV
1062
      if (pSnode->replicaId <= 0) {
×
1063
        mstsError("no available snode now, mainSnodeId:%d, replicaId:%d", mainSnodeId, pSnode->replicaId);
×
1064
        mndReleaseSnode(pMnode, pSnode);
×
1065
        return 0;
×
1066
      }
1067

UNCOV
1068
      snodeId = pSnode->replicaId;
×
1069
      mndReleaseSnode(pMnode, pSnode);
×
1070
      
UNCOV
1071
      continue;
×
1072
    }
1073

UNCOV
1074
    mstsError("no available snode now, mainSnodeId:%d, followerSnodeId:%d", mainSnodeId, snodeId);
×
1075
    return 0;
×
1076
  }
1077

UNCOV
1078
_exit:
×
1079

UNCOV
1080
  if (code) {
×
1081
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1082
  }
1083

UNCOV
1084
  return 0;
×
1085
}
1086

1087
int32_t msmAssignRandomSnodeId(SMnode* pMnode, int64_t streamId) {
627,205✔
1088
  int32_t code = TSDB_CODE_SUCCESS;
627,205✔
1089
  int32_t lino = 0;
627,205✔
1090
  int32_t snodeIdx = 0;
627,205✔
1091
  int32_t snodeId = 0;
627,205✔
1092
  void      *pIter = NULL;
627,205✔
1093
  SSnodeObj *pObj = NULL;
627,205✔
1094
  bool alive = false;
627,205✔
1095
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
627,205✔
1096
  if (snodeNum <= 0) {
627,205✔
1097
    mstsInfo("no available snode now, num:%d", snodeNum);
4,320✔
1098
    goto _exit;
4,320✔
1099
  }
1100

1101
  int32_t snodeTarget = taosRand() % snodeNum;
622,885✔
1102

1103
  while (1) {
1104
    pIter = sdbFetch(pMnode->pSdb, SDB_SNODE, pIter, (void **)&pObj);
657,051✔
1105
    if (pIter == NULL) {
657,051✔
UNCOV
1106
      if (0 == snodeId) {
×
1107
        mstsError("no alive snode now, snodeNum:%d", snodeNum);
×
1108
        break;
×
1109
      }
1110
      
UNCOV
1111
      snodeId = 0;
×
1112
      continue;
×
1113
    }
1114

1115
    code = msmIsSnodeAlive(pMnode, pObj->id, streamId, &alive);
657,051✔
1116
    if (code) {
657,051✔
UNCOV
1117
      sdbRelease(pMnode->pSdb, pObj);
×
1118
      sdbCancelFetch(pMnode->pSdb, pIter);
×
1119
      pObj = NULL;
×
1120
      TAOS_CHECK_EXIT(code);
×
1121
    }
1122
    
1123
    if (!alive) {
657,051✔
UNCOV
1124
      sdbRelease(pMnode->pSdb, pObj);
×
1125
      continue;
×
1126
    }
1127

1128
    snodeId = pObj->id;
657,051✔
1129
    if (snodeIdx == snodeTarget) {
657,051✔
1130
      sdbRelease(pMnode->pSdb, pObj);
622,885✔
1131
      sdbCancelFetch(pMnode->pSdb, pIter);
622,885✔
1132
      pObj = NULL;
622,885✔
1133
      goto _exit;
622,885✔
1134
    }
1135

1136
    sdbRelease(pMnode->pSdb, pObj);
34,166✔
1137
    snodeIdx++;
34,166✔
1138
  }
1139

1140
_exit:
627,205✔
1141

1142
  if (code) {
627,205✔
UNCOV
1143
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1144
  }
1145

1146
  if (0 == snodeId) {
627,205✔
1147
    terrno = TSDB_CODE_SNODE_NO_AVAILABLE_NODE;
4,320✔
1148
  }
1149

1150
  return snodeId;
627,205✔
1151
}
1152

1153
int32_t msmAssignTaskSnodeId(SMnode* pMnode, SStreamObj* pStream, bool isStatic) {
805,101✔
1154
  int64_t streamId = pStream->pCreate->streamId;
805,101✔
1155
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
805,101✔
1156
  int32_t snodeId = 0;
805,101✔
1157
  if (snodeNum <= 0) {
805,101✔
UNCOV
1158
    mstsInfo("no available snode now, num:%d", snodeNum);
×
1159
    goto _exit;
×
1160
  }
1161

1162
  snodeId = isStatic ? msmRetrieveStaticSnodeId(pMnode, pStream) : msmAssignRandomSnodeId(pMnode, streamId);
805,101✔
1163

1164
_exit:
805,101✔
1165

1166
  if (0 == snodeId) {
805,101✔
UNCOV
1167
    terrno = TSDB_CODE_SNODE_NO_AVAILABLE_NODE;
×
1168
  }
1169

1170
  return snodeId;
805,101✔
1171
}
1172

1173

1174
static int32_t msmBuildTriggerTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
203,697✔
1175
  int32_t code = TSDB_CODE_SUCCESS;
203,697✔
1176
  int32_t lino = 0;
203,697✔
1177
  int64_t streamId = pStream->pCreate->streamId;
203,697✔
1178

1179
  pInfo->triggerTask = taosMemoryCalloc(1, sizeof(SStmTaskStatus));
203,697✔
1180
  TSDB_CHECK_NULL(pInfo->triggerTask, code, lino, _exit, terrno);
203,697✔
1181

1182
  pInfo->triggerTask->id.taskId = pCtx->triggerTaskId;
203,697✔
1183
  pInfo->triggerTask->id.deployId = 0;
203,697✔
1184
  pInfo->triggerTask->id.seriousId = msmAssignTaskSeriousId();
203,697✔
1185
  pInfo->triggerTask->id.nodeId = pCtx->triggerNodeId;
203,697✔
1186
  pInfo->triggerTask->id.taskIdx = 0;
203,697✔
1187
  pInfo->triggerTask->type = STREAM_TRIGGER_TASK;
203,697✔
1188
  pInfo->triggerTask->lastUpTs = pCtx->currTs;
203,697✔
1189
  pInfo->triggerTask->pStream = pInfo;
203,697✔
1190

1191
  SStmTaskDeploy info = {0};
203,697✔
1192
  info.task.type = pInfo->triggerTask->type;
203,697✔
1193
  info.task.streamId = streamId;
203,697✔
1194
  info.task.taskId =  pInfo->triggerTask->id.taskId;
203,697✔
1195
  info.task.seriousId = pInfo->triggerTask->id.seriousId;
203,697✔
1196
  info.task.nodeId =  pInfo->triggerTask->id.nodeId;
203,697✔
1197
  info.task.taskIdx =  pInfo->triggerTask->id.taskIdx;
203,697✔
1198
  TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pInfo, &info, pStream));
203,697✔
1199
  TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
203,697✔
1200
  
1201
  (void)atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
203,697✔
1202

1203
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pInfo->triggerTask));
203,697✔
1204
  TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, pInfo->triggerTask, 1, -1));
203,697✔
1205

1206
_exit:
203,697✔
1207

1208
  if (code) {
203,697✔
UNCOV
1209
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1210
  }
1211

1212
  return code;
203,697✔
1213
}
1214

1215
static int32_t msmTDAddSingleTrigReader(SStmGrpCtx* pCtx, SStmTaskStatus* pState, int32_t nodeId, SStmStatus* pInfo, int64_t streamId) {
318,527✔
1216
  int32_t code = TSDB_CODE_SUCCESS;
318,527✔
1217
  int32_t lino = 0;
318,527✔
1218

1219
  pState->id.taskId = msmAssignTaskId();
318,527✔
1220
  pState->id.deployId = 0;
318,527✔
1221
  pState->id.seriousId = msmAssignTaskSeriousId();
318,527✔
1222
  pState->id.nodeId = nodeId;
318,527✔
1223
  pState->id.taskIdx = 0;
318,527✔
1224
  pState->type = STREAM_READER_TASK;
318,527✔
1225
  pState->flags = STREAM_FLAG_TRIGGER_READER;
318,527✔
1226
  pState->status = STREAM_STATUS_UNDEPLOYED;
318,527✔
1227
  pState->lastUpTs = pCtx->currTs;
318,527✔
1228
  pState->pStream = pInfo;
318,527✔
1229
  
1230
  SStmTaskDeploy info = {0};
318,527✔
1231
  info.task.type = pState->type;
318,527✔
1232
  info.task.streamId = streamId;
318,527✔
1233
  info.task.taskId = pState->id.taskId;
318,527✔
1234
  info.task.flags = pState->flags;
318,527✔
1235
  info.task.seriousId = pState->id.seriousId;
318,527✔
1236
  info.task.nodeId = pState->id.nodeId;
318,527✔
1237
  info.task.taskIdx = pState->id.taskIdx;
318,527✔
1238
  TAOS_CHECK_EXIT(msmBuildReaderDeployInfo(&info, NULL, pInfo, true));
318,527✔
1239
  TAOS_CHECK_EXIT(msmTDAddToVgroupMap(mStreamMgmt.toDeployVgMap, &info, streamId));
318,527✔
1240

1241
_exit:
318,527✔
1242

1243
  if (code) {
318,527✔
UNCOV
1244
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1245
  }
1246

1247
  return code;
318,527✔
1248
}
1249

1250
static int32_t msmTDAddTrigReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
203,697✔
1251
  int32_t code = TSDB_CODE_SUCCESS;
203,697✔
1252
  int32_t lino = 0;
203,697✔
1253
  int64_t streamId = pStream->pCreate->streamId;
203,697✔
1254
  SSdb   *pSdb = pCtx->pMnode->pSdb;
203,697✔
1255
  SStmTaskStatus* pState = NULL;
203,697✔
1256
  SVgObj *pVgroup = NULL;
203,697✔
1257
  SDbObj* pDb = NULL;
203,697✔
1258
  
1259
  switch (pStream->pCreate->triggerTblType) {
203,697✔
1260
    case TSDB_NORMAL_TABLE:
94,669✔
1261
    case TSDB_CHILD_TABLE:
1262
    case TSDB_VIRTUAL_CHILD_TABLE:
1263
    case TSDB_VIRTUAL_NORMAL_TABLE: {
1264
      pInfo->trigReaders = taosArrayInit_s(sizeof(SStmTaskStatus), 1);
94,669✔
1265
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
94,669✔
1266
      pState = taosArrayGet(pInfo->trigReaders, 0);
94,669✔
1267
      
1268
      TAOS_CHECK_EXIT(msmTDAddSingleTrigReader(pCtx, pState, pStream->pCreate->triggerTblVgId, pInfo, streamId));
94,669✔
1269
      break;
94,669✔
1270
    }
1271
    case TSDB_SUPER_TABLE: {
107,835✔
1272
      pDb = mndAcquireDb(pCtx->pMnode, pStream->pCreate->triggerDB);
107,835✔
1273
      if (NULL == pDb) {
107,835✔
UNCOV
1274
        code = terrno;
×
1275
        mstsError("failed to acquire db %s, error:%s", pStream->pCreate->triggerDB, terrstr());
×
1276
        goto _exit;
×
1277
      }
1278

1279
      pInfo->trigReaders = taosArrayInit(pDb->cfg.numOfVgroups, sizeof(SStmTaskStatus));
107,835✔
1280
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
107,835✔
1281
      
1282
      void *pIter = NULL;
107,835✔
1283
      while (1) {
553,237✔
1284
        SStmTaskDeploy info = {0};
661,072✔
1285
        pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
661,072✔
1286
        if (pIter == NULL) {
661,072✔
1287
          break;
107,835✔
1288
        }
1289
      
1290
        if (pVgroup->dbUid == pDb->uid && !pVgroup->isTsma) {
553,237✔
1291
          pState = taosArrayReserve(pInfo->trigReaders, 1);
157,968✔
1292

1293
          code = msmTDAddSingleTrigReader(pCtx, pState, pVgroup->vgId, pInfo, streamId);
157,968✔
1294
          if (code) {
157,968✔
UNCOV
1295
            sdbRelease(pSdb, pVgroup);
×
1296
            sdbCancelFetch(pSdb, pIter);
×
1297
            pVgroup = NULL;
×
1298
            TAOS_CHECK_EXIT(code);
×
1299
          }
1300
        }
1301

1302
        sdbRelease(pSdb, pVgroup);
553,237✔
1303
      }
1304
      break;
107,835✔
1305
    }
1306
    default:
1,193✔
1307
      mstsDebug("%s ignore triggerTblType %d", __FUNCTION__, pStream->pCreate->triggerTblType);
1,193✔
1308
      break;
1,193✔
1309
  }
1310

1311
_exit:
203,697✔
1312

1313
  mndReleaseDb(pCtx->pMnode, pDb);
203,697✔
1314

1315
  if (code) {
203,697✔
UNCOV
1316
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1317
  }
1318

1319
  return code;
203,697✔
1320
}
1321

1322
int32_t msmUPAddScanTask(SStmGrpCtx* pCtx, SStreamObj* pStream, char* scanPlan, int32_t vgId, int64_t taskId) {
282,613✔
1323
  int32_t code = TSDB_CODE_SUCCESS;
282,613✔
1324
  int32_t lino = 0;
282,613✔
1325
  SSubplan* pSubplan = NULL;
282,613✔
1326
  int64_t streamId = pStream->pCreate->streamId;
282,613✔
1327
  int64_t key[2] = {streamId, 0};
282,613✔
1328
  SStmTaskSrcAddr addr;
279,247✔
1329
  TAOS_CHECK_EXIT(nodesStringToNode(scanPlan, (SNode**)&pSubplan));
282,613✔
1330
  addr.isFromCache = false;
282,613✔
1331
  
1332
  if (MNODE_HANDLE == vgId) {
282,613✔
UNCOV
1333
    mndGetMnodeEpSet(pCtx->pMnode, &addr.epset);
×
1334
  } else if (vgId > MNODE_HANDLE) {
282,613✔
1335
    addr.epset = mndGetVgroupEpsetById(pCtx->pMnode, vgId);
282,613✔
1336
  } else {
UNCOV
1337
    mstsError("invalid vgId %d in scanPlan", vgId);
×
1338
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1339
  }
1340
  
1341
  addr.taskId = taskId;
282,613✔
1342
  addr.vgId = vgId;
282,613✔
1343
  addr.groupId = pSubplan->id.groupId;
282,613✔
1344

1345
  key[1] = pSubplan->id.subplanId;
282,613✔
1346

1347
  SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
282,613✔
1348
  if (NULL == ppRes) {
282,613✔
1349
    SArray* pRes = taosArrayInit(1, sizeof(addr));
282,613✔
1350
    TSDB_CHECK_NULL(pRes, code, lino, _exit, terrno);
282,613✔
1351
    TSDB_CHECK_NULL(taosArrayPush(pRes, &addr), code, lino, _exit, terrno);
565,226✔
1352
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.toUpdateScanMap, key, sizeof(key), &pRes, POINTER_BYTES));
282,613✔
1353
  } else {
UNCOV
1354
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &addr), code, lino, _exit, terrno);
×
1355
  }
1356

1357
  mstsDebug("calcReader %" PRIx64 " added to toUpdateScan, vgId:%d, groupId:%d, subplanId:%d", taskId, vgId, pSubplan->id.groupId, pSubplan->id.subplanId);
282,613✔
1358
  
1359
  (void)atomic_add_fetch_32(&mStreamMgmt.toUpdateScanNum, 1);
282,613✔
1360
  
1361
_exit:
282,613✔
1362

1363
  nodesDestroyNode((SNode*)pSubplan);
282,613✔
1364

1365
  if (code) {
282,613✔
UNCOV
1366
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1367
  }
1368

1369
  return code;
282,613✔
1370
}
1371

1372
int32_t msmUPAddCacheTask(SStmGrpCtx* pCtx, SStreamCalcScan* pScan, SStreamObj* pStream) {
97,291✔
1373
  int32_t code = TSDB_CODE_SUCCESS;
97,291✔
1374
  int32_t lino = 0;
97,291✔
1375
  SSubplan* pSubplan = NULL;
97,291✔
1376
  int64_t streamId = pStream->pCreate->streamId;
97,291✔
1377
  int64_t key[2] = {streamId, 0};
97,291✔
1378
  TAOS_CHECK_EXIT(nodesStringToNode(pScan->scanPlan, (SNode**)&pSubplan));
97,291✔
1379

1380
  SStmTaskSrcAddr addr;
97,291✔
1381
  addr.isFromCache = true;
97,291✔
1382
  addr.epset = mndGetDnodeEpsetById(pCtx->pMnode, pCtx->triggerNodeId);
97,291✔
1383
  addr.taskId = pCtx->triggerTaskId;
97,291✔
1384
  addr.vgId = pCtx->triggerNodeId;
97,291✔
1385
  addr.groupId = pSubplan->id.groupId;
97,291✔
1386

1387
  key[1] = pSubplan->id.subplanId;
97,291✔
1388
  SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
97,291✔
1389
  if (NULL == ppRes) {
97,291✔
1390
    SArray* pRes = taosArrayInit(1, sizeof(addr));
97,291✔
1391
    TSDB_CHECK_NULL(pRes, code, lino, _exit, terrno);
97,291✔
1392
    TSDB_CHECK_NULL(taosArrayPush(pRes, &addr), code, lino, _exit, terrno);
194,582✔
1393
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.toUpdateScanMap, key, sizeof(key), &pRes, POINTER_BYTES));
97,291✔
1394
  } else {
UNCOV
1395
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &addr), code, lino, _exit, terrno);
×
1396
  }
1397
  
1398
  (void)atomic_add_fetch_32(&mStreamMgmt.toUpdateScanNum, 1);
97,291✔
1399
  
1400
_exit:
97,291✔
1401

1402
  nodesDestroyNode((SNode*)pSubplan);
97,291✔
1403
  
1404
  if (code) {
97,291✔
UNCOV
1405
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1406
  }
1407

1408
  return code;
97,291✔
1409
}
1410

1411

1412
static int32_t msmTDAddSingleCalcReader(SStmGrpCtx* pCtx, SStmTaskStatus* pState, int32_t taskIdx, int32_t nodeId, void* calcScanPlan, SStmStatus* pInfo, int64_t streamId) {
286,609✔
1413
  int32_t code = TSDB_CODE_SUCCESS;
286,609✔
1414
  int32_t lino = 0;
286,609✔
1415

1416
  TAOS_CHECK_EXIT(mstGetScanUidFromPlan(streamId, calcScanPlan, &pState->id.uid));
286,609✔
1417

1418
  pState->id.taskId = msmAssignTaskId();
286,609✔
1419
  pState->id.deployId = 0;
286,609✔
1420
  pState->id.seriousId = msmAssignTaskSeriousId();
286,609✔
1421
  pState->id.nodeId = nodeId;
286,609✔
1422
  pState->id.taskIdx = taskIdx;
286,609✔
1423
  pState->type = STREAM_READER_TASK;
286,609✔
1424
  pState->flags = 0;
286,609✔
1425
  pState->status = STREAM_STATUS_UNDEPLOYED;
286,609✔
1426
  pState->lastUpTs = pCtx->currTs;
286,609✔
1427
  pState->pStream = pInfo;
286,609✔
1428
  
1429
  SStmTaskDeploy info = {0};
286,609✔
1430
  info.task.type = pState->type;
286,609✔
1431
  info.task.streamId = streamId;
286,609✔
1432
  info.task.taskId = pState->id.taskId;
286,609✔
1433
  info.task.flags = pState->flags;
286,609✔
1434
  info.task.seriousId = pState->id.seriousId;
286,609✔
1435
  info.task.nodeId = pState->id.nodeId;
286,609✔
1436
  info.task.taskIdx = pState->id.taskIdx;
286,609✔
1437
  TAOS_CHECK_EXIT(msmBuildReaderDeployInfo(&info, calcScanPlan, pInfo, false));
286,609✔
1438
  TAOS_CHECK_EXIT(msmTDAddToVgroupMap(mStreamMgmt.toDeployVgMap, &info, streamId));
286,609✔
1439

1440
_exit:
286,609✔
1441

1442
  if (code) {
286,609✔
UNCOV
1443
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1444
  }
1445

1446
  return code;
286,609✔
1447
}
1448

1449

1450
static int32_t msmTDAddCalcReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
203,697✔
1451
  int32_t code = TSDB_CODE_SUCCESS;
203,697✔
1452
  int32_t lino = 0;
203,697✔
1453
  int32_t calcTasksNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
203,697✔
1454
  int64_t streamId = pStream->pCreate->streamId;
203,697✔
1455
  SStmTaskStatus* pState = NULL;
203,697✔
1456
  pInfo->calcReaders = tdListNew(sizeof(SStmTaskStatus));
203,697✔
1457
  TSDB_CHECK_NULL(pInfo->calcReaders, code, lino, _exit, terrno);
203,697✔
1458

1459
  
1460
  for (int32_t i = 0; i < calcTasksNum; ++i) {
583,175✔
1461
    SStreamCalcScan* pScan = taosArrayGet(pInfo->pCreate->calcScanPlanList, i);
379,478✔
1462
    if (pScan->readFromCache) {
379,478✔
1463
      TAOS_CHECK_EXIT(msmUPAddCacheTask(pCtx, pScan, pStream));
97,291✔
1464
      continue;
97,291✔
1465
    }
1466
    
1467
    int32_t vgNum = taosArrayGetSize(pScan->vgList);
282,187✔
1468
    for (int32_t m = 0; m < vgNum; ++m) {
564,374✔
1469
      pState = tdListReserve(pInfo->calcReaders);
282,187✔
1470
      TSDB_CHECK_NULL(pState, code, lino, _exit, terrno);
282,187✔
1471

1472
      TAOS_CHECK_EXIT(msmTDAddSingleCalcReader(pCtx, pState, i, *(int32_t*)taosArrayGet(pScan->vgList, m), pScan->scanPlan, pInfo, streamId));
282,187✔
1473
      TAOS_CHECK_EXIT(msmUPAddScanTask(pCtx, pStream, pScan->scanPlan, pState->id.nodeId, pState->id.taskId));
282,187✔
1474
    }
1475
  }
1476

1477
_exit:
203,697✔
1478

1479
  if (code) {
203,697✔
UNCOV
1480
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1481
  }
1482

1483
  return code;
203,697✔
1484
}
1485

1486

1487

1488
static int32_t msmUPPrepareReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
426✔
1489
  int32_t code = TSDB_CODE_SUCCESS;
426✔
1490
  int32_t lino = 0;
426✔
1491
  int64_t streamId = pStream->pCreate->streamId;
426✔
1492
  int32_t calcTasksNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
426✔
1493
  if (calcTasksNum <= 0) {
426✔
UNCOV
1494
    mstsDebug("no calc scan plan, ignore parepare reader tasks, readerNum:%d", (int32_t)MST_LIST_SIZE(pInfo->calcReaders));
×
1495
    return code;    
×
1496
  }
1497
  
1498
  SListNode* pNode = listHead(pInfo->calcReaders);
426✔
1499
  
1500
  for (int32_t i = 0; i < calcTasksNum; ++i) {
852✔
1501
    SStreamCalcScan* pScan = taosArrayGet(pStream->pCreate->calcScanPlanList, i);
426✔
1502
    if (pScan->readFromCache) {
426✔
UNCOV
1503
      TAOS_CHECK_EXIT(msmUPAddCacheTask(pCtx, pScan, pStream));
×
1504
      continue;
×
1505
    }
1506
    
1507
    int32_t vgNum = taosArrayGetSize(pScan->vgList);
426✔
1508
    for (int32_t m = 0; m < vgNum; ++m) {
852✔
1509
      SStmTaskStatus* pReader = (SStmTaskStatus*)pNode->data;
426✔
1510
      TAOS_CHECK_EXIT(msmUPAddScanTask(pCtx, pStream, pScan->scanPlan, pReader->id.nodeId, pReader->id.taskId));
426✔
1511
      pNode = TD_DLIST_NODE_NEXT(pNode);
426✔
1512
    }
1513
  }
1514

1515
_exit:
426✔
1516

1517
  if (code) {
426✔
UNCOV
1518
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1519
  }
1520

1521
  return code;
426✔
1522
}
1523

1524
static int32_t msmBuildReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
203,697✔
1525
  int32_t code = TSDB_CODE_SUCCESS;
203,697✔
1526
  int32_t lino = 0;
203,697✔
1527
  int64_t streamId = pStream->pCreate->streamId;
203,697✔
1528
  
1529
  TAOS_CHECK_EXIT(msmTDAddTrigReaderTasks(pCtx, pInfo, pStream));
203,697✔
1530
  TAOS_CHECK_EXIT(msmTDAddCalcReaderTasks(pCtx, pInfo, pStream));
203,697✔
1531

1532
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, pInfo->trigReaders, NULL, NULL));
203,697✔
1533
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, pInfo->calcReaders, NULL));
203,697✔
1534
  
1535
  TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, pInfo->trigReaders, NULL, NULL, true));
203,697✔
1536
  TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, pInfo->calcReaders, NULL, false));
203,697✔
1537
  
1538
_exit:
203,697✔
1539

1540
  if (code) {
203,697✔
UNCOV
1541
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1542
  }
1543
  
1544
  return code;
203,697✔
1545
}
1546

1547
int32_t msmUpdatePlanSourceAddr(SStreamTask* pTask, int64_t streamId, SSubplan* plan, int64_t clientId, SStmTaskSrcAddr* pSrc, int32_t msgType, int64_t srcSubplanId) {
1,173,348✔
1548
  SDownstreamSourceNode source = {
1,173,348✔
1549
      .type = QUERY_NODE_DOWNSTREAM_SOURCE,
1550
      .clientId = clientId,
1551
      .taskId = pSrc->taskId,
1,173,348✔
1552
      .sId = 0,
1553
      .execId = 0,
1554
      .fetchMsgType = msgType,
1555
      .localExec = false,
1556
  };
1557

1558
  source.addr.epSet = pSrc->epset;
1,173,348✔
1559
  source.addr.nodeId = pSrc->vgId;
1,173,348✔
1560

1561
  msttDebug("try to update subplan %d grp %d sourceAddr from subplan %" PRId64 ", clientId:%" PRIx64 ", srcTaskId:%" PRIx64 ", srcNodeId:%d, msgType:%s", 
1,173,348✔
1562
      plan->id.subplanId, pSrc->groupId, srcSubplanId, source.clientId, source.taskId, source.addr.nodeId, TMSG_INFO(source.fetchMsgType));
1563
  
1564
  return qSetSubplanExecutionNode(plan, pSrc->groupId, &source);
1,173,348✔
1565
}
1566

1567
int32_t msmGetTaskIdFromSubplanId(SStreamObj* pStream, SArray* pRunners, int32_t beginIdx, int32_t subplanId, int64_t* taskId, SStreamTask** ppParent) {
34,062✔
1568
  int64_t streamId = pStream->pCreate->streamId;
34,062✔
1569
  int32_t runnerNum = taosArrayGetSize(pRunners);
34,062✔
1570
  for (int32_t i = beginIdx; i < runnerNum; ++i) {
85,155✔
1571
    SStmTaskDeploy* pDeploy = taosArrayGet(pRunners, i);
85,155✔
1572
    SSubplan* pPlan = pDeploy->msg.runner.pPlan;
85,155✔
1573
    if (pPlan->id.subplanId == subplanId) {
85,155✔
1574
      *taskId = pDeploy->task.taskId;
34,062✔
1575
      *ppParent = &pDeploy->task;
34,062✔
1576
      return TSDB_CODE_SUCCESS;
34,062✔
1577
    }
1578
  }
1579

UNCOV
1580
  mstsError("subplanId %d not found in runner list", subplanId);
×
1581

UNCOV
1582
  return TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
1583
}
1584

1585
int32_t msmUpdateLowestPlanSourceAddr(SSubplan* pPlan, SStmTaskDeploy* pDeploy, int64_t streamId) {
635,466✔
1586
  int32_t code = TSDB_CODE_SUCCESS;
635,466✔
1587
  int32_t lino = 0;
635,466✔
1588
  int64_t key[2] = {streamId, -1};
635,466✔
1589
  SNode* pNode = NULL;
635,466✔
1590
  SStreamTask* pTask = &pDeploy->task;
635,466✔
1591
  FOREACH(pNode, pPlan->pChildren) {
1,808,814✔
1592
    if (QUERY_NODE_VALUE != nodeType(pNode)) {
1,173,348✔
1593
      msttDebug("node type %d is not valueNode, skip it", nodeType(pNode));
34,062✔
1594
      continue;
34,062✔
1595
    }
1596
    
1597
    SValueNode* pVal = (SValueNode*)pNode;
1,139,286✔
1598
    if (TSDB_DATA_TYPE_BIGINT != pVal->node.resType.type) {
1,139,286✔
UNCOV
1599
      msttWarn("invalid value node data type %d for runner's child subplan", pVal->node.resType.type);
×
1600
      continue;
×
1601
    }
1602

1603
    key[1] = MND_GET_RUNNER_SUBPLANID(pVal->datum.i);
1,139,286✔
1604

1605
    SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
1,139,286✔
1606
    if (NULL == ppRes) {
1,139,286✔
UNCOV
1607
      msttError("lowest runner subplan ID:%d,%d can't get its child ID:%" PRId64 " addr", pPlan->id.groupId, pPlan->id.subplanId, key[1]);
×
1608
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1609
    }
1610

1611
    int32_t childrenNum = taosArrayGetSize(*ppRes);
1,139,286✔
1612
    for (int32_t i = 0; i < childrenNum; ++i) {
2,278,572✔
1613
      SStmTaskSrcAddr* pAddr = taosArrayGet(*ppRes, i);
1,139,286✔
1614
      TAOS_CHECK_EXIT(msmUpdatePlanSourceAddr(pTask, streamId, pPlan, pDeploy->task.taskId, pAddr, pAddr->isFromCache ? TDMT_STREAM_FETCH_FROM_CACHE : TDMT_STREAM_FETCH, key[1]));
1,139,286✔
1615
    }
1616
  }
1617

1618
_exit:
635,466✔
1619

1620
  if (code) {
635,466✔
UNCOV
1621
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1622
  }
1623

1624
  return code;
635,466✔
1625
}
1626

1627
int32_t msmUpdateRunnerPlan(SStmGrpCtx* pCtx, SArray* pRunners, int32_t beginIdx, SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
635,466✔
1628
  int32_t code = TSDB_CODE_SUCCESS;
635,466✔
1629
  int32_t lino = 0;
635,466✔
1630
  SSubplan* pPlan = pDeploy->msg.runner.pPlan;
635,466✔
1631
  SStreamTask* pTask = &pDeploy->task;
635,466✔
1632
  SStreamTask* parentTask = NULL;
635,466✔
1633
  int64_t streamId = pStream->pCreate->streamId;
635,466✔
1634

1635
  TAOS_CHECK_EXIT(msmUpdateLowestPlanSourceAddr(pPlan, pDeploy, streamId));
635,466✔
1636

1637
  SNode* pTmp = NULL;
635,466✔
1638
  WHERE_EACH(pTmp, pPlan->pChildren) {
1,808,814✔
1639
    if (QUERY_NODE_VALUE == nodeType(pTmp)) {
1,173,348✔
1640
      ERASE_NODE(pPlan->pChildren);
1,139,286✔
1641
      continue;
1,139,286✔
1642
    }
1643
    WHERE_NEXT;
34,062✔
1644
  }
1645
  nodesClearList(pPlan->pChildren);
635,466✔
1646
  pPlan->pChildren = NULL;
635,466✔
1647

1648
  if (NULL == pPlan->pParents) {
635,466✔
1649
    goto _exit;
601,404✔
1650
  }
1651

1652
  SNode* pNode = NULL;
34,062✔
1653
  int64_t parentTaskId = 0;
34,062✔
1654
  SStmTaskSrcAddr addr = {0};
34,062✔
1655
  addr.taskId = pDeploy->task.taskId;
34,062✔
1656
  addr.vgId = pDeploy->task.nodeId;
34,062✔
1657
  addr.groupId = pPlan->id.groupId;
34,062✔
1658
  addr.epset = mndGetDnodeEpsetById(pCtx->pMnode, pDeploy->task.nodeId);
34,062✔
1659
  FOREACH(pNode, pPlan->pParents) {
68,124✔
1660
    SSubplan* pSubplan = (SSubplan*)pNode;
34,062✔
1661
    TAOS_CHECK_EXIT(msmGetTaskIdFromSubplanId(pStream, pRunners, beginIdx, pSubplan->id.subplanId, &parentTaskId, &parentTask));
34,062✔
1662
    TAOS_CHECK_EXIT(msmUpdatePlanSourceAddr(parentTask, streamId, pSubplan, parentTaskId, &addr, TDMT_STREAM_FETCH_FROM_RUNNER, pPlan->id.subplanId));
34,062✔
1663
  }
1664
  
1665
_exit:
625,368✔
1666

1667
  if (code) {
635,466✔
UNCOV
1668
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1669
  }
1670

1671
  return code;
635,466✔
1672
}
1673

1674
int32_t msmUpdateRunnerPlans(SStmGrpCtx* pCtx, SArray* pRunners, SStreamObj* pStream) {
601,404✔
1675
  int32_t code = TSDB_CODE_SUCCESS;
601,404✔
1676
  int32_t lino = 0;
601,404✔
1677
  int64_t streamId = pStream->pCreate->streamId;
601,404✔
1678
  int32_t runnerNum = taosArrayGetSize(pRunners);
601,404✔
1679
  
1680
  for (int32_t i = 0; i < runnerNum; ++i) {
1,236,870✔
1681
    SStmTaskDeploy* pDeploy = taosArrayGet(pRunners, i);
635,466✔
1682
    TAOS_CHECK_EXIT(msmUpdateRunnerPlan(pCtx, pRunners, i, pDeploy, pStream));
635,466✔
1683
    TAOS_CHECK_EXIT(nodesNodeToString((SNode*)pDeploy->msg.runner.pPlan, false, (char**)&pDeploy->msg.runner.pPlan, NULL));
635,466✔
1684

1685
    SStreamTask* pTask = &pDeploy->task;
635,466✔
1686
    msttDebugL("runner updated task plan:%s", (const char*)pDeploy->msg.runner.pPlan);
635,466✔
1687
  }
1688

1689
_exit:
601,404✔
1690

1691
  if (code) {
601,404✔
UNCOV
1692
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1693
  }
1694

1695
  return code;
601,404✔
1696
}
1697

1698
int32_t msmBuildRunnerTasksImpl(SStmGrpCtx* pCtx, SQueryPlan* pDag, SStmStatus* pInfo, SStreamObj* pStream) {
200,184✔
1699
  int32_t code = 0;
200,184✔
1700
  int32_t lino = 0;
200,184✔
1701
  int64_t streamId = pStream->pCreate->streamId;
200,184✔
1702
  SArray* deployTaskList = NULL;
200,184✔
1703
  SArray* deployList = NULL;
200,184✔
1704
  int32_t deployNodeId = 0;
200,184✔
1705
  SStmTaskStatus* pState = NULL;
200,184✔
1706
  int32_t taskIdx = 0;
200,184✔
1707
  SNodeListNode *plans = NULL;
200,184✔
1708
  int32_t        taskNum = 0;
200,184✔
1709
  int32_t        totalTaskNum = 0;
200,184✔
1710

1711
  if (pDag->numOfSubplans <= 0) {
200,184✔
UNCOV
1712
    mstsError("invalid subplan num:%d", pDag->numOfSubplans);
×
1713
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1714
  }
1715

1716
  if (pDag->numOfSubplans != pStream->pCreate->numOfCalcSubplan) {
200,184✔
UNCOV
1717
    mstsError("numOfCalcSubplan %d mismatch with numOfSubplans %d", pStream->pCreate->numOfCalcSubplan, pDag->numOfSubplans);
×
1718
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1719
  }
1720

1721
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
200,184✔
1722
  if (levelNum <= 0) {
200,184✔
UNCOV
1723
    mstsError("invalid level num:%d", levelNum);
×
1724
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1725
  }
1726

1727
  int32_t        lowestLevelIdx = levelNum - 1;
200,184✔
1728
  
1729
  plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, 0);
200,184✔
1730
  if (QUERY_NODE_NODE_LIST != nodeType(plans)) {
200,184✔
UNCOV
1731
    mstsError("invalid level plan, level:0, planNodeType:%d", nodeType(plans));
×
1732
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1733
  }
1734
  
1735
  taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
200,184✔
1736
  if (taskNum != 1) {
200,184✔
UNCOV
1737
    mstsError("invalid level plan number:%d, level:0", taskNum);
×
1738
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1739
  }
1740

1741
  deployTaskList = taosArrayInit_s(sizeof(SStmTaskDeploy), pDag->numOfSubplans);
200,184✔
1742
  TSDB_CHECK_NULL(deployTaskList, code, lino, _exit, terrno);
200,184✔
1743
  
1744
  for (int32_t deployId = 0; deployId < pInfo->runnerDeploys; ++deployId) {
800,736✔
1745
    totalTaskNum = 0;
600,552✔
1746

1747
    deployList = pInfo->runners[deployId];
600,552✔
1748
    deployNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, (0 == deployId) ? true : false);
600,552✔
1749
    if (!GOT_SNODE(deployNodeId)) {
600,552✔
UNCOV
1750
      TAOS_CHECK_EXIT(terrno);
×
1751
    }
1752

1753
    taskIdx = 0;
600,552✔
1754
    
1755
    for (int32_t i = lowestLevelIdx; i >= 0; --i) {
1,218,135✔
1756
      plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
617,583✔
1757
      if (NULL == plans) {
617,583✔
UNCOV
1758
        mstsError("empty level plan, level:%d", i);
×
1759
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1760
      }
1761

1762
      if (QUERY_NODE_NODE_LIST != nodeType(plans)) {
617,583✔
UNCOV
1763
        mstsError("invalid level plan, level:%d, planNodeType:%d", i, nodeType(plans));
×
1764
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1765
      }
1766

1767
      taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
617,583✔
1768
      if (taskNum <= 0) {
617,583✔
UNCOV
1769
        mstsError("invalid level plan number:%d, level:%d", taskNum, i);
×
1770
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1771
      }
1772

1773
      totalTaskNum += taskNum;
617,583✔
1774
      if (totalTaskNum > pDag->numOfSubplans) {
617,583✔
UNCOV
1775
        mstsError("current totalTaskNum %d is bigger than numOfSubplans %d, level:%d", totalTaskNum, pDag->numOfSubplans, i);
×
1776
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1777
      }
1778

1779
      for (int32_t n = 0; n < taskNum; ++n) {
1,252,197✔
1780
        SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
634,614✔
1781
        pState = taosArrayReserve(deployList, 1);
634,614✔
1782

1783
        pState->id.taskId = msmAssignTaskId();
634,614✔
1784
        pState->id.deployId = deployId;
634,614✔
1785
        pState->id.seriousId = msmAssignTaskSeriousId();
634,614✔
1786
        pState->id.nodeId = deployNodeId;
634,614✔
1787
        pState->id.taskIdx = MND_SET_RUNNER_TASKIDX(i, n);
634,614✔
1788
        pState->type = STREAM_RUNNER_TASK;
634,614✔
1789
        pState->flags = (0 == i) ? STREAM_FLAG_TOP_RUNNER : 0;
634,614✔
1790
        pState->status = STREAM_STATUS_UNDEPLOYED;
634,614✔
1791
        pState->lastUpTs = pCtx->currTs;
634,614✔
1792
        pState->pStream = pInfo;
634,614✔
1793

1794
        SStmTaskDeploy* pDeploy = taosArrayGet(deployTaskList, taskIdx++);
634,614✔
1795
        pDeploy->task.type = pState->type;
634,614✔
1796
        pDeploy->task.streamId = streamId;
634,614✔
1797
        pDeploy->task.taskId = pState->id.taskId;
634,614✔
1798
        pDeploy->task.flags = pState->flags;
634,614✔
1799
        pDeploy->task.seriousId = pState->id.seriousId;
634,614✔
1800
        pDeploy->task.deployId = pState->id.deployId;
634,614✔
1801
        pDeploy->task.nodeId = pState->id.nodeId;
634,614✔
1802
        pDeploy->task.taskIdx = pState->id.taskIdx;
634,614✔
1803
        TAOS_CHECK_EXIT(msmBuildRunnerDeployInfo(pDeploy, plan, pStream, pInfo, 0 == i));
634,614✔
1804

1805
        SStreamTask* pTask = &pDeploy->task;
634,614✔
1806
        msttDebug("runner task deploy built, subplan level:%d, taskIdx:%d, groupId:%d, subplanId:%d",
634,614✔
1807
            i, pTask->taskIdx, plan->id.groupId, plan->id.subplanId);
1808
      }
1809

1810
      mstsDebug("deploy %d level %d initialized, taskNum:%d", deployId, i, taskNum);
617,583✔
1811
    }
1812

1813
    if (totalTaskNum != pDag->numOfSubplans) {
600,552✔
UNCOV
1814
      mstsError("totalTaskNum %d mis-match with numOfSubplans %d", totalTaskNum, pDag->numOfSubplans);
×
1815
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1816
    }
1817

1818
    TAOS_CHECK_EXIT(msmUpdateRunnerPlans(pCtx, deployTaskList, pStream));
600,552✔
1819

1820
    TAOS_CHECK_EXIT(msmTDAddRunnersToSnodeMap(deployTaskList, pStream));
600,552✔
1821

1822
    nodesDestroyNode((SNode *)pDag);
600,552✔
1823
    pDag = NULL;
600,552✔
1824
    
1825
    TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pDag));
600,552✔
1826

1827
    mstsDebug("total %d runner tasks added for deploy %d", totalTaskNum, deployId);
600,552✔
1828
  }
1829

1830
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
800,736✔
1831
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, pInfo->runners[i], NULL, NULL));
600,552✔
1832
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, pInfo->runners[i], NULL, 0, i));
600,552✔
1833
  }
1834
  
1835
  pInfo->runnerNum = totalTaskNum;
200,184✔
1836
  
1837
_exit:
200,184✔
1838

1839
  if (code) {
200,184✔
UNCOV
1840
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1841
  }
1842

1843
  taosArrayDestroy(deployTaskList);
200,184✔
1844
  nodesDestroyNode((SNode *)pDag);
200,184✔
1845

1846
  return code;
200,184✔
1847
}
1848

1849
int32_t msmReBuildRunnerTasks(SStmGrpCtx* pCtx, SQueryPlan* pDag, SStmStatus* pInfo, SStreamObj* pStream, SStmTaskAction* pAction) {
426✔
1850
  int32_t code = 0;
426✔
1851
  int32_t lino = 0;
426✔
1852
  int64_t streamId = pStream->pCreate->streamId;
426✔
1853
  int32_t newNodeId = 0;
426✔
1854
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
426✔
1855
  int32_t        lowestLevelIdx = levelNum - 1;
426✔
1856
  SNodeListNode *plans = NULL;
426✔
1857
  int32_t        taskNum = 0;
426✔
1858
  int32_t        totalTaskNum = 0;
426✔
1859
  int32_t        deployId = 0;
426✔
1860
  SStmTaskStatus* pRunner = NULL;
426✔
1861
  SStmTaskStatus* pStartRunner = NULL;
426✔
1862
  int32_t taskIdx = 0;
426✔
1863
  SArray* deployTaskList = taosArrayInit_s(sizeof(SStmTaskDeploy), pDag->numOfSubplans);
426✔
1864
  TSDB_CHECK_NULL(deployTaskList, code, lino, _exit, terrno);
426✔
1865

1866
  for (int32_t r = 0; r < pAction->deployNum; ++r) {
1,278✔
1867
    deployId = pAction->deployId[r];
852✔
1868

1869
    pRunner = taosArrayGet(pInfo->runners[deployId], 0);
852✔
1870

1871
    pStartRunner = pRunner;
852✔
1872
    totalTaskNum = 0;
852✔
1873

1874
    newNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, (0 == r) ? true : false);
852✔
1875
    if (!GOT_SNODE(newNodeId)) {
852✔
UNCOV
1876
      TAOS_CHECK_EXIT(terrno);
×
1877
    }
1878

1879
    taskIdx = 0;
852✔
1880
    
1881
    for (int32_t i = lowestLevelIdx; i >= 0; --i) {
1,704✔
1882
      plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
852✔
1883
      taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
852✔
1884
      totalTaskNum += taskNum;
852✔
1885

1886
      pRunner->flags &= STREAM_FLAG_REDEPLOY_RUNNER;
852✔
1887
      
1888
      for (int32_t n = 0; n < taskNum; ++n) {
1,704✔
1889
        SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
852✔
1890

1891
        int32_t newTaskIdx = MND_SET_RUNNER_TASKIDX(i, n);
852✔
1892
        if (pRunner->id.taskIdx != newTaskIdx) {
852✔
UNCOV
1893
          mstsError("runner TASK:%" PRId64 " taskIdx %d mismatch with newTaskIdx:%d", pRunner->id.taskId, pRunner->id.taskIdx, newTaskIdx);
×
1894
          TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
1895
        }
1896

1897
        pRunner->id.nodeId = newNodeId;
852✔
1898

1899
        SStmTaskDeploy* pDeploy = taosArrayGet(deployTaskList, taskIdx++);
852✔
1900
        pDeploy->task.type = pRunner->type;
852✔
1901
        pDeploy->task.streamId = streamId;
852✔
1902
        pDeploy->task.taskId = pRunner->id.taskId;
852✔
1903
        pDeploy->task.flags = pRunner->flags;
852✔
1904
        pDeploy->task.seriousId = pRunner->id.seriousId;
852✔
1905
        pDeploy->task.nodeId = pRunner->id.nodeId;
852✔
1906
        pDeploy->task.taskIdx = pRunner->id.taskIdx;
852✔
1907
        TAOS_CHECK_EXIT(msmBuildRunnerDeployInfo(pDeploy, plan, pStream, pInfo, 0 == i));
852✔
1908

1909
        pRunner++;
852✔
1910
      }
1911

1912
      mstsDebug("level %d initialized, taskNum:%d", i, taskNum);
852✔
1913
    }
1914

1915
    TAOS_CHECK_EXIT(msmUpdateRunnerPlans(pCtx, deployTaskList, pStream));
852✔
1916

1917
    TAOS_CHECK_EXIT(msmTDAddRunnersToSnodeMap(deployTaskList, pStream));
852✔
1918

1919
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, pInfo->runners[deployId], NULL, 0, deployId));
852✔
1920

1921
    nodesDestroyNode((SNode *)pDag);
852✔
1922
    pDag = NULL;
852✔
1923

1924
    TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pDag));
852✔
1925
  }
1926

1927
_exit:
426✔
1928

1929
  if (code) {
426✔
UNCOV
1930
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1931
  }
1932

1933
  nodesDestroyNode((SNode *)pDag);
426✔
1934
  taosArrayDestroy(deployTaskList);
426✔
1935

1936
  return code;
426✔
1937
}
1938

1939

1940
int32_t msmSetStreamRunnerExecReplica(int64_t streamId, SStmStatus* pInfo) {
194,238✔
1941
  int32_t code = TSDB_CODE_SUCCESS;
194,238✔
1942
  int32_t lino = 0;
194,238✔
1943
  //STREAMTODO 
1944
  
1945
  pInfo->runnerDeploys = MND_STREAM_RUNNER_DEPLOY_NUM;
194,238✔
1946
  pInfo->runnerReplica = MND_STREAM_RUNNER_REPLICA_NUM;
194,238✔
1947

1948
_exit:
194,238✔
1949

1950
  if (code) {
194,238✔
UNCOV
1951
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1952
  }
1953

1954
  return code;
194,238✔
1955
}
1956

1957

1958
static int32_t msmBuildRunnerTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
203,697✔
1959
  if (NULL == pStream->pCreate->calcPlan) {
203,697✔
1960
    return TSDB_CODE_SUCCESS;
3,513✔
1961
  }
1962
  
1963
  int32_t code = TSDB_CODE_SUCCESS;
200,184✔
1964
  int32_t lino = 0;
200,184✔
1965
  int64_t streamId = pStream->pCreate->streamId;
200,184✔
1966
  SQueryPlan* pPlan = NULL;
200,184✔
1967

1968
  TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pPlan));
200,184✔
1969

1970
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
800,736✔
1971
    pInfo->runners[i] = taosArrayInit(pPlan->numOfSubplans, sizeof(SStmTaskStatus));
600,552✔
1972
    TSDB_CHECK_NULL(pInfo->runners[i], code, lino, _exit, terrno);
600,552✔
1973
  }
1974

1975
  code = msmBuildRunnerTasksImpl(pCtx, pPlan, pInfo, pStream);
200,184✔
1976
  pPlan = NULL;
200,184✔
1977
  
1978
  TAOS_CHECK_EXIT(code);
200,184✔
1979

1980
  taosHashClear(mStreamMgmt.toUpdateScanMap);
200,184✔
1981
  mStreamMgmt.toUpdateScanNum = 0;
200,184✔
1982

1983
_exit:
200,184✔
1984

1985
  nodesDestroyNode((SNode *)pPlan);
200,184✔
1986

1987
  if (code) {
200,184✔
UNCOV
1988
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1989
  }
1990

1991
  return code;
200,184✔
1992
}
1993

1994

1995
static int32_t msmBuildStreamTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
203,697✔
1996
  int32_t code = TSDB_CODE_SUCCESS;
203,697✔
1997
  int32_t lino = 0;
203,697✔
1998
  int64_t streamId = pStream->pCreate->streamId;
203,697✔
1999

2000
  mstsInfo("start to deploy stream tasks, deployTimes:%" PRId64, pInfo->deployTimes);
203,697✔
2001

2002
  pCtx->triggerTaskId = msmAssignTaskId();
203,697✔
2003
  pCtx->triggerNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
203,697✔
2004
  if (!GOT_SNODE(pCtx->triggerNodeId)) {
203,697✔
UNCOV
2005
    TAOS_CHECK_EXIT(terrno);
×
2006
  }
2007

2008
  TAOS_CHECK_EXIT(msmBuildReaderTasks(pCtx, pInfo, pStream));
203,697✔
2009
  TAOS_CHECK_EXIT(msmBuildRunnerTasks(pCtx, pInfo, pStream));
203,697✔
2010
  TAOS_CHECK_EXIT(msmBuildTriggerTasks(pCtx, pInfo, pStream));
203,697✔
2011
  
2012
_exit:
203,697✔
2013

2014
  if (code) {
203,697✔
UNCOV
2015
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2016
  }
2017

2018
  return code;
203,697✔
2019
}
2020

UNCOV
2021
static int32_t msmInitTrigReaderList(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
×
2022
  int32_t code = TSDB_CODE_SUCCESS;
×
2023
  int32_t lino = 0;
×
2024
  int64_t streamId = pStream->pCreate->streamId;
×
2025
  SSdb   *pSdb = pCtx->pMnode->pSdb;
×
2026
  SStmTaskStatus* pState = NULL;
×
2027
  SDbObj* pDb = NULL;
×
2028
  
UNCOV
2029
  switch (pStream->pCreate->triggerTblType) {
×
2030
    case TSDB_NORMAL_TABLE:
×
2031
    case TSDB_CHILD_TABLE:
2032
    case TSDB_VIRTUAL_CHILD_TABLE:
2033
    case TSDB_VIRTUAL_NORMAL_TABLE: {
UNCOV
2034
      pInfo->trigReaders = taosArrayInit_s(sizeof(SStmTaskStatus), 1);
×
2035
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
×
2036
      pInfo->trigReaderNum = 1;
×
2037
      break;
×
2038
    }
UNCOV
2039
    case TSDB_SUPER_TABLE: {
×
2040
      pDb = mndAcquireDb(pCtx->pMnode, pStream->pCreate->triggerDB);
×
2041
      if (NULL == pDb) {
×
2042
        code = terrno;
×
2043
        mstsError("failed to acquire db %s, error:%s", pStream->pCreate->triggerDB, terrstr());
×
2044
        goto _exit;
×
2045
      }
2046

UNCOV
2047
      pInfo->trigReaders = taosArrayInit(pDb->cfg.numOfVgroups, sizeof(SStmTaskStatus));
×
2048
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
×
2049
      pInfo->trigReaderNum = pDb->cfg.numOfVgroups;
×
2050
      mndReleaseDb(pCtx->pMnode, pDb);
×
2051
      pDb = NULL;
×
2052
      break;
×
2053
    }
UNCOV
2054
    default:
×
2055
      pInfo->trigReaderNum = 0;
×
2056
      mstsDebug("%s ignore triggerTblType %d", __FUNCTION__, pStream->pCreate->triggerTblType);
×
2057
      break;
×
2058
  }
2059

UNCOV
2060
_exit:
×
2061

UNCOV
2062
  if (code) {
×
2063
    mndReleaseDb(pCtx->pMnode, pDb);
×
2064
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2065
  }
2066

UNCOV
2067
  return code;
×
2068
}
2069

2070

2071
static int32_t msmInitStmStatus(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStreamObj* pStream, bool initList) {
197,751✔
2072
  int32_t code = TSDB_CODE_SUCCESS;
197,751✔
2073
  int32_t lino = 0;
197,751✔
2074
  int64_t streamId = pStream->pCreate->streamId;
197,751✔
2075

2076
  pStatus->lastActionTs = INT64_MIN;
197,751✔
2077

2078
  if (NULL == pStatus->streamName) {
197,751✔
2079
    pStatus->streamName = taosStrdup(pStream->name);
197,751✔
2080
    TSDB_CHECK_NULL(pStatus->streamName, code, lino, _exit, terrno);
197,751✔
2081
  }
2082

2083
  TAOS_CHECK_EXIT(tCloneStreamCreateDeployPointers(pStream->pCreate, &pStatus->pCreate));
197,751✔
2084
  
2085
  if (pStream->pCreate->numOfCalcSubplan > 0) {
197,751✔
2086
    pStatus->runnerNum = pStream->pCreate->numOfCalcSubplan;
194,238✔
2087
    
2088
    TAOS_CHECK_EXIT(msmSetStreamRunnerExecReplica(streamId, pStatus));
194,238✔
2089
  }
2090

2091
  if (initList) {
197,751✔
UNCOV
2092
    TAOS_CHECK_EXIT(msmInitTrigReaderList(pCtx, pStatus, pStream));
×
2093

UNCOV
2094
    int32_t subPlanNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
×
2095
    if (subPlanNum > 0) {
×
2096
      pStatus->calcReaderNum = subPlanNum;
×
2097
      pStatus->calcReaders = tdListNew(sizeof(SStmTaskStatus));
×
2098
      TSDB_CHECK_NULL(pStatus->calcReaders, code, lino, _exit, terrno);
×
2099
    }
2100

UNCOV
2101
    if (pStatus->runnerNum > 0) {
×
2102
      for (int32_t i = 0; i < pStatus->runnerDeploys; ++i) {
×
2103
        pStatus->runners[i] = taosArrayInit(pStatus->runnerNum, sizeof(SStmTaskStatus));
×
2104
        TSDB_CHECK_NULL(pStatus->runners[i], code, lino, _exit, terrno);
×
2105
      }
2106
    }
2107
  }
2108
  
2109
_exit:
197,751✔
2110

2111
  if (code) {
197,751✔
UNCOV
2112
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2113
  }
2114

2115
  return code;
197,751✔
2116
}
2117

2118
static int32_t msmDeployStreamTasks(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmStatus* pStatus) {
203,697✔
2119
  int32_t code = TSDB_CODE_SUCCESS;
203,697✔
2120
  int32_t lino = 0;
203,697✔
2121
  int64_t streamId = pStream->pCreate->streamId;
203,697✔
2122
  SStmStatus info = {0};
203,697✔
2123

2124
  if (NULL == pStatus) {
203,697✔
2125
    TAOS_CHECK_EXIT(msmInitStmStatus(pCtx, &info, pStream, false));
197,751✔
2126

2127
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.streamMap, &streamId, sizeof(streamId), &info, sizeof(info)));
197,751✔
2128

2129
    pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
197,751✔
2130
  }
2131
  
2132
  TAOS_CHECK_EXIT(msmBuildStreamTasks(pCtx, pStatus, pStream));
203,697✔
2133

2134
  mstLogSStmStatus("stream deployed", streamId, pStatus);
203,697✔
2135

2136
_exit:
203,697✔
2137

2138
  if (code) {
203,697✔
UNCOV
2139
    if (NULL != pStatus) {
×
2140
      msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
2141
      mstsError("stream build error:%s, will try to stop current stream", tstrerror(code));
×
2142
    }
2143
    
UNCOV
2144
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2145
  }
2146

2147
  return code;
203,697✔
2148
}
2149

2150

2151
static int32_t msmSTRemoveStream(int64_t streamId, bool fromStreamMap) {
9,999✔
2152
  int32_t code = TSDB_CODE_SUCCESS;
9,999✔
2153
  void* pIter = NULL;
9,999✔
2154

2155
  while ((pIter = taosHashIterate(mStreamMgmt.toDeployVgMap, pIter))) {
13,248✔
2156
    SStmVgTasksToDeploy* pVg = (SStmVgTasksToDeploy*)pIter;
3,249✔
2157
    (void)mstWaitLock(&pVg->lock, true);
3,249✔
2158

2159
    int32_t taskNum = taosArrayGetSize(pVg->taskList);
3,249✔
2160
    if (atomic_load_32(&pVg->deployed) == taskNum) {
3,249✔
UNCOV
2161
      taosRUnLockLatch(&pVg->lock);
×
2162
      continue;
×
2163
    }
2164

2165
    for (int32_t i = 0; i < taskNum; ++i) {
13,357✔
2166
      SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, i);
10,108✔
2167
      if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
10,108✔
2168
        continue;
10,108✔
2169
      }
2170

UNCOV
2171
      mstDestroySStmTaskToDeployExt(pExt);
×
UNCOV
2172
      pExt->deployed = true;
×
2173
    }
2174
    
2175
    taosRUnLockLatch(&pVg->lock);
3,249✔
2176
  }
2177

2178
  while ((pIter = taosHashIterate(mStreamMgmt.toDeploySnodeMap, pIter))) {
21,580✔
2179
    SStmSnodeTasksDeploy* pSnode = (SStmSnodeTasksDeploy*)pIter;
11,581✔
2180
    (void)mstWaitLock(&pSnode->lock, true);
11,581✔
2181

2182
    int32_t taskNum = taosArrayGetSize(pSnode->triggerList);
11,581✔
2183
    if (atomic_load_32(&pSnode->triggerDeployed) != taskNum) {
11,581✔
2184
      for (int32_t i = 0; i < taskNum; ++i) {
10,108✔
2185
        SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, i);
6,137✔
2186
        if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
6,137✔
2187
          continue;
5,776✔
2188
        }
2189
        
2190
        mstDestroySStmTaskToDeployExt(pExt);
361✔
2191
        pExt->deployed = true;
361✔
2192
      }
2193
    }
2194

2195
    taskNum = taosArrayGetSize(pSnode->runnerList);
11,581✔
2196
    if (atomic_load_32(&pSnode->runnerDeployed) != taskNum) {
11,581✔
2197
      for (int32_t i = 0; i < taskNum; ++i) {
35,104✔
2198
        SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, i);
23,523✔
2199
        if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
23,523✔
2200
          continue;
22,440✔
2201
        }
2202
        
2203
        mstDestroySStmTaskToDeployExt(pExt);
1,083✔
2204
        pExt->deployed = true;
1,083✔
2205
      }
2206
    }
2207

2208
    taosRUnLockLatch(&pSnode->lock);
11,581✔
2209
  }
2210

2211
  
2212
  while ((pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter))) {
46,857✔
2213
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
36,858✔
2214
    code = taosHashRemove(pSnode->streamTasks, &streamId, sizeof(streamId));
36,858✔
2215
    if (TSDB_CODE_SUCCESS == code) {
36,858✔
2216
      mstsDebug("stream removed from snodeMap %d, remainStreams:%d", *(int32_t*)taosHashGetKey(pIter, NULL), (int32_t)taosHashGetSize(pSnode->streamTasks));
13,674✔
2217
    }
2218
  }
2219

2220
  while ((pIter = taosHashIterate(mStreamMgmt.vgroupMap, pIter))) {
29,788✔
2221
    SStmVgroupStatus* pVg = (SStmVgroupStatus*)pIter;
19,789✔
2222
    code = taosHashRemove(pVg->streamTasks, &streamId, sizeof(streamId));
19,789✔
2223
    if (TSDB_CODE_SUCCESS == code) {
19,789✔
2224
      mstsDebug("stream removed from vgroupMap %d, remainStreams:%d", *(int32_t*)taosHashGetKey(pIter, NULL), (int32_t)taosHashGetSize(pVg->streamTasks));
13,642✔
2225
    }
2226
  }
2227

2228
  size_t keyLen = 0;
9,999✔
2229
  while ((pIter = taosHashIterate(mStreamMgmt.taskMap, pIter))) {
417,512✔
2230
    int64_t* pStreamId = taosHashGetKey(pIter, &keyLen);
407,513✔
2231
    if (*pStreamId == streamId) {
407,513✔
2232
      int64_t taskId = *(pStreamId + 1);
59,320✔
2233
      code = taosHashRemove(mStreamMgmt.taskMap, pStreamId, keyLen);
59,320✔
2234
      if (code) {
59,320✔
UNCOV
2235
        mstsError("TASK:%" PRIx64 " remove from taskMap failed, error:%s", taskId, tstrerror(code));
×
2236
      } else {
2237
        mstsDebug("TASK:%" PRIx64 " removed from taskMap", taskId);
59,320✔
2238
      }
2239
    }
2240
  }
2241

2242
  if (fromStreamMap) {
9,999✔
2243
    code = taosHashRemove(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
3,331✔
2244
    if (code) {
3,331✔
UNCOV
2245
      mstsError("stream remove from streamMap failed, error:%s", tstrerror(code));
×
2246
    } else {
2247
      mstsDebug("stream removed from streamMap, remains:%d", taosHashGetSize(mStreamMgmt.streamMap));
3,331✔
2248
    }
2249
  }
2250
  
2251
  return code;
9,999✔
2252
}
2253

2254
static void msmResetStreamForRedeploy(int64_t streamId, SStmStatus* pStatus) {
6,668✔
2255
  mstsInfo("try to reset stream for redeploy, stopped:%d, current deployTimes:%" PRId64, atomic_load_8(&pStatus->stopped), pStatus->deployTimes);
6,668✔
2256
  
2257
  (void)msmSTRemoveStream(streamId, false);  
6,668✔
2258

2259
  mstResetSStmStatus(pStatus);
6,668✔
2260

2261
  pStatus->deployTimes++;
6,668✔
2262
}
6,668✔
2263

2264
static int32_t msmLaunchStreamDeployAction(SStmGrpCtx* pCtx, SStmStreamAction* pAction) {
204,803✔
2265
  int32_t code = TSDB_CODE_SUCCESS;
204,803✔
2266
  int32_t lino = 0;
204,803✔
2267
  int64_t streamId = pAction->streamId;
204,803✔
2268
  char* streamName = pAction->streamName;
204,803✔
2269
  SStreamObj* pStream = NULL;
204,803✔
2270
  int8_t stopped = 0;
204,803✔
2271

2272
  SStmStatus* pStatus = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
204,803✔
2273
  if (pStatus) {
204,803✔
2274
    stopped = atomic_load_8(&pStatus->stopped);
6,668✔
2275
    if (0 == stopped) {
6,668✔
2276
      mstsDebug("stream %s will try to reset and redeploy it", pAction->streamName);
1,083✔
2277
      msmResetStreamForRedeploy(streamId, pStatus);
1,083✔
2278
    } else {
2279
      if (MST_IS_USER_STOPPED(stopped) && !pAction->userAction) {
5,585✔
UNCOV
2280
        mstsWarn("stream %s already stopped by user, stopped:%d, ignore deploy it", pAction->streamName, stopped);
×
2281
        return code;
×
2282
      }
2283
      
2284
      if (stopped == atomic_val_compare_exchange_8(&pStatus->stopped, stopped, 0)) {
5,585✔
2285
        mstsDebug("stream %s will try to reset and redeploy it from stopped %d", pAction->streamName, stopped);
5,585✔
2286
        msmResetStreamForRedeploy(streamId, pStatus);
5,585✔
2287
      }
2288
    }
2289
  }
2290

2291
  code = mndAcquireStream(pCtx->pMnode, streamName, &pStream);
204,803✔
2292
  if (TSDB_CODE_MND_STREAM_NOT_EXIST == code) {
204,803✔
2293
    mstsWarn("stream %s no longer exists, ignore deploy", streamName);
384✔
2294
    return TSDB_CODE_SUCCESS;
384✔
2295
  }
2296

2297
  TAOS_CHECK_EXIT(code);
204,419✔
2298

2299
  if (pStatus && pStream->pCreate->streamId != streamId) {
204,419✔
UNCOV
2300
    mstsWarn("stream %s already dropped by user, ignore deploy it", pAction->streamName);
×
2301
    atomic_store_8(&pStatus->stopped, 2);
×
2302
    mstsInfo("set stream %s stopped by user since streamId mismatch", streamName);
×
2303
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_EXIST);
×
2304
  }
2305

2306
  int8_t userStopped = atomic_load_8(&pStream->userStopped);
204,419✔
2307
  int8_t userDropped = atomic_load_8(&pStream->userDropped);
204,419✔
2308
  if (userStopped || userDropped) {
204,419✔
2309
    mstsWarn("stream %s is stopped %d or removing %d, ignore deploy", streamName, userStopped, userDropped);
722✔
2310
    goto _exit;
722✔
2311
  }
2312
  
2313
  TAOS_CHECK_EXIT(msmDeployStreamTasks(pCtx, pStream, pStatus));
203,697✔
2314

2315
_exit:
204,419✔
2316

2317
  mndReleaseStream(pCtx->pMnode, pStream);
204,419✔
2318

2319
  if (code) {
204,419✔
UNCOV
2320
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2321
  }
2322

2323
  return code;
204,419✔
2324
}
2325

2326
static int32_t msmReLaunchReaderTask(SStreamObj* pStream, SStmTaskAction* pAction, SStmStatus* pStatus) {
2,166✔
2327
  int32_t code = TSDB_CODE_SUCCESS;
2,166✔
2328
  int32_t lino = 0;
2,166✔
2329
  int64_t streamId = pAction->streamId;
2,166✔
2330
  SStmTaskStatus** ppTask = taosHashGet(mStreamMgmt.taskMap, &pAction->streamId, sizeof(pAction->streamId) + sizeof(pAction->id.taskId));
2,166✔
2331
  if (NULL == ppTask) {
2,166✔
UNCOV
2332
    mstsError("TASK:%" PRId64 " not in taskMap, remain:%d", pAction->id.taskId, taosHashGetSize(mStreamMgmt.taskMap));
×
2333
    TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
2334
  }
2335
  
2336
  SStmTaskDeploy info = {0};
2,166✔
2337
  info.task.type = pAction->type;
2,166✔
2338
  info.task.streamId = pAction->streamId;
2,166✔
2339
  info.task.taskId = pAction->id.taskId;
2,166✔
2340
  info.task.seriousId = (*ppTask)->id.seriousId;
2,166✔
2341
  info.task.nodeId = pAction->id.nodeId;
2,166✔
2342
  info.task.taskIdx = pAction->id.taskIdx;
2,166✔
2343
  
2344
  bool isTriggerReader = STREAM_IS_TRIGGER_READER(pAction->flag);
2,166✔
2345
  SStreamCalcScan* scanPlan = NULL;
2,166✔
2346
  if (!isTriggerReader) {
2,166✔
2347
    scanPlan = taosArrayGet(pStatus->pCreate->calcScanPlanList, pAction->id.taskIdx);
1,083✔
2348
    if (NULL == scanPlan) {
1,083✔
UNCOV
2349
      mstsError("fail to get TASK:%" PRId64 " scanPlan, taskIdx:%d, scanPlanNum:%zu", 
×
2350
          pAction->id.taskId, pAction->id.taskIdx, taosArrayGetSize(pStatus->pCreate->calcScanPlanList));
UNCOV
2351
      TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
2352
    }
2353
  }
2354
  
2355
  TAOS_CHECK_EXIT(msmBuildReaderDeployInfo(&info, scanPlan ? scanPlan->scanPlan : NULL, pStatus, isTriggerReader));
2,166✔
2356
  TAOS_CHECK_EXIT(msmTDAddToVgroupMap(mStreamMgmt.toDeployVgMap, &info, pAction->streamId));
2,166✔
2357

2358
_exit:
2,166✔
2359

2360
  if (code) {
2,166✔
UNCOV
2361
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2362
  }
2363

2364
  return code;
2,166✔
2365
}
2366

2367
/*
2368
static int32_t msmReLaunchTriggerTask(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmTaskAction* pAction, SStmStatus* pStatus) {
2369
  int32_t code = TSDB_CODE_SUCCESS;
2370
  int32_t lino = 0;
2371
  int64_t streamId = pAction->streamId;
2372
  SStmTaskStatus** ppTask = taosHashGet(mStreamMgmt.taskMap, &pAction->streamId, sizeof(pAction->streamId) + sizeof(pAction->id.taskId));
2373
  if (NULL == ppTask) {
2374
    mstsError("TASK:%" PRId64 " not in taskMap, remain:%d", pAction->id.taskId, taosHashGetSize(mStreamMgmt.taskMap));
2375
    TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
2376
  }
2377
  
2378
  (*ppTask)->id.nodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
2379
  if (!GOT_SNODE((*ppTask)->id.nodeId)) {
2380
    mstsError("no avaible snode for deploying trigger task, seriousId: %" PRId64, (*ppTask)->id.seriousId);
2381
    return TSDB_CODE_SUCCESS;
2382
  }
2383
  
2384
  SStmTaskDeploy info = {0};
2385
  info.task.type = pAction->type;
2386
  info.task.streamId = streamId;
2387
  info.task.taskId = pAction->id.taskId;
2388
  info.task.seriousId = (*ppTask)->id.seriousId;
2389
  info.task.nodeId = (*ppTask)->id.nodeId;
2390
  info.task.taskIdx = pAction->id.taskIdx;
2391
  
2392
  TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pStatus, &info, pStream));
2393
  TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
2394
  TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, *ppTask, 1, -1));
2395
  
2396
  atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
2397

2398
_exit:
2399

2400
  if (code) {
2401
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
2402
  }
2403

2404
  return code;
2405
}
2406
*/
2407

2408
static int32_t msmReLaunchRunnerDeploy(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmTaskAction* pAction, SStmStatus* pStatus) {
426✔
2409
  int32_t code = TSDB_CODE_SUCCESS;
426✔
2410
  int32_t lino = 0;
426✔
2411
  int64_t streamId = pAction->streamId;
426✔
2412
  
2413
/*
2414
  if (pAction->triggerStatus) {
2415
    pCtx->triggerTaskId = pAction->triggerStatus->id.taskId;
2416
    pAction->triggerStatus->id.nodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
2417
    if (!GOT_SNODE(pAction->triggerStatus->id.nodeId)) {
2418
      mstsError("no avaible snode for deploying trigger task, seriousId:%" PRId64, pAction->triggerStatus->id.seriousId);
2419
      return TSDB_CODE_SUCCESS;
2420
    }
2421
  
2422
    pCtx->triggerNodeId = pAction->triggerStatus->id.nodeId;
2423
  } else {
2424
*/
2425
  pCtx->triggerTaskId = pStatus->triggerTask->id.taskId;
426✔
2426
  pCtx->triggerNodeId = pStatus->triggerTask->id.nodeId;
426✔
2427
//  }
2428
  
2429
  TAOS_CHECK_EXIT(msmUPPrepareReaderTasks(pCtx, pStatus, pStream));
426✔
2430
  
2431
  SQueryPlan* pPlan = NULL;
426✔
2432
  TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pPlan));
426✔
2433
  
2434
  TAOS_CHECK_EXIT(msmReBuildRunnerTasks(pCtx, pPlan, pStatus, pStream, pAction));
426✔
2435
  
2436
  taosHashClear(mStreamMgmt.toUpdateScanMap);
426✔
2437
  mStreamMgmt.toUpdateScanNum = 0;
426✔
2438
  
2439
/*
2440
  if (pAction->triggerStatus) {
2441
    SStmTaskDeploy info = {0};
2442
    info.task.type = STREAM_TRIGGER_TASK;
2443
    info.task.streamId = streamId;
2444
    info.task.taskId = pCtx->triggerTaskId;
2445
    info.task.seriousId = pAction->triggerStatus->id.seriousId;
2446
    info.task.nodeId = pCtx->triggerNodeId;
2447
    info.task.taskIdx = 0;
2448
  
2449
    TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pStatus, &info, pStream));
2450
    TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
2451
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, pAction->triggerStatus, 1, -1));
2452
    
2453
    atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
2454
  }
2455
*/
2456

2457
_exit:
426✔
2458

2459
  if (code) {
426✔
UNCOV
2460
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2461
  }
2462

2463
  return code;
426✔
2464
}
2465

2466

2467
static int32_t msmLaunchTaskDeployAction(SStmGrpCtx* pCtx, SStmTaskAction* pAction) {
2,592✔
2468
  int32_t code = TSDB_CODE_SUCCESS;
2,592✔
2469
  int32_t lino = 0;
2,592✔
2470
  int64_t streamId = pAction->streamId;
2,592✔
2471
  int64_t taskId = pAction->id.taskId;
2,592✔
2472
  SStreamObj* pStream = NULL;
2,592✔
2473

2474
  mstsDebug("start to handle stream tasks action, action task type:%s", gStreamTaskTypeStr[pAction->type]);
2,592✔
2475

2476
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &pAction->streamId, sizeof(pAction->streamId));
2,592✔
2477
  if (NULL == pStatus) {
2,592✔
UNCOV
2478
    mstsWarn("stream not in streamMap, remain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
2479
    return TSDB_CODE_SUCCESS;
×
2480
  }
2481

2482
  int8_t stopped = atomic_load_8(&pStatus->stopped);
2,592✔
2483
  if (stopped) {
2,592✔
UNCOV
2484
    mstsWarn("stream %s is already stopped %d, ignore task deploy", pStatus->streamName, stopped);
×
2485
    return TSDB_CODE_SUCCESS;
×
2486
  }
2487

2488
  code = mndAcquireStream(pCtx->pMnode, pStatus->streamName, &pStream);
2,592✔
2489
  if (TSDB_CODE_MND_STREAM_NOT_EXIST == code) {
2,592✔
UNCOV
2490
    mstsWarn("stream %s no longer exists, ignore task deploy", pStatus->streamName);
×
2491
    return TSDB_CODE_SUCCESS;
×
2492
  }
2493

2494
  TAOS_CHECK_EXIT(code);
2,592✔
2495

2496
  int8_t userStopped = atomic_load_8(&pStream->userStopped);
2,592✔
2497
  int8_t userDropped = atomic_load_8(&pStream->userDropped);
2,592✔
2498
  if (userStopped || userDropped) {
2,592✔
UNCOV
2499
    mstsWarn("stream %s is stopped %d or removing %d, ignore task deploy", pStatus->streamName, userStopped, userDropped);
×
2500
    goto _exit;
×
2501
  }
2502

2503
  switch (pAction->type) {
2,592✔
2504
    case STREAM_READER_TASK:
2,166✔
2505
      TAOS_CHECK_EXIT(msmReLaunchReaderTask(pStream, pAction, pStatus));
2,166✔
2506
      break;
2,166✔
2507
/*
2508
    case STREAM_TRIGGER_TASK:
2509
      TAOS_CHECK_EXIT(msmReLaunchTriggerTask(pCtx, pStream, pAction, pStatus));
2510
      break;
2511
*/
2512
    case STREAM_RUNNER_TASK:
426✔
2513
      if (pAction->multiRunner) {
426✔
2514
        TAOS_CHECK_EXIT(msmReLaunchRunnerDeploy(pCtx, pStream, pAction, pStatus));
426✔
2515
      } else {
UNCOV
2516
        mstsError("runner TASK:%" PRId64 " requires relaunch", pAction->id.taskId);
×
2517
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
2518
      }
2519
      break;
426✔
UNCOV
2520
    default:
×
2521
      mstsError("TASK:%" PRId64 " invalid task type:%d", pAction->id.taskId, pAction->type);
×
2522
      TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
2523
      break;
×
2524
  }
2525

2526
_exit:
2,592✔
2527

2528
  if (pStream) {
2,592✔
2529
    mndReleaseStream(pCtx->pMnode, pStream);
2,592✔
2530
  }
2531

2532
  if (code) {
2,592✔
UNCOV
2533
    msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
2534
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2535
  }
2536

2537
  return code;
2,592✔
2538
}
2539

UNCOV
2540
static int32_t msmTDRemoveStream(int64_t streamId) {
×
2541
  void* pIter = NULL;
×
2542
  
UNCOV
2543
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
×
2544
    while ((pIter = taosHashIterate(mStreamMgmt.toDeployVgMap, pIter))) {
×
2545
      SStmVgTasksToDeploy* pVg = (SStmVgTasksToDeploy*)pIter;
×
2546
      int32_t taskNum = taosArrayGetSize(pVg->taskList);
×
2547
      if (atomic_load_32(&pVg->deployed) == taskNum) {
×
2548
        continue;
×
2549
      }
2550
      
UNCOV
2551
      for (int32_t i = 0; i < taskNum; ++i) {
×
2552
        SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, i);
×
2553
        if (pExt->deploy.task.streamId == streamId && !pExt->deployed) {
×
2554
          pExt->deployed = true;
×
2555
        }
2556
      }
2557
    }
2558
  }
2559

UNCOV
2560
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0) {
×
2561
    while ((pIter = taosHashIterate(mStreamMgmt.toDeploySnodeMap, pIter))) {
×
2562
      SStmSnodeTasksDeploy* pSnode = (SStmSnodeTasksDeploy*)pIter;
×
2563
      int32_t taskNum = taosArrayGetSize(pSnode->triggerList);
×
2564
      if (atomic_load_32(&pSnode->triggerDeployed) != taskNum) {
×
2565
        for (int32_t i = 0; i < taskNum; ++i) {
×
2566
          SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, i);
×
2567
          if (pExt->deploy.task.streamId == streamId && !pExt->deployed) {
×
2568
            pExt->deployed = true;
×
2569
          }
2570
        }
2571
      }
2572

UNCOV
2573
      taskNum = taosArrayGetSize(pSnode->runnerList);
×
2574
      if (atomic_load_32(&pSnode->runnerDeployed) != taskNum) {
×
2575
        for (int32_t i = 0; i < taskNum; ++i) {
×
2576
          SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, i);
×
2577
          if (pExt->deploy.task.streamId == streamId && !pExt->deployed) {
×
2578
            pExt->deployed = true;
×
2579
          }
2580
        }
2581
      }
2582
    }
2583
  }
2584

UNCOV
2585
  return TSDB_CODE_SUCCESS;
×
2586
}
2587

2588
static int32_t msmRemoveStreamFromMaps(SMnode* pMnode, int64_t streamId) {
3,331✔
2589
  int32_t code = TSDB_CODE_SUCCESS;
3,331✔
2590
  int32_t lino = 0;
3,331✔
2591

2592
  mstsInfo("start to remove stream from maps, current stream num:%d", taosHashGetSize(mStreamMgmt.streamMap));
3,331✔
2593

2594
  TAOS_CHECK_EXIT(msmSTRemoveStream(streamId, true));
3,331✔
2595

2596
_exit:
3,331✔
2597

2598
  if (code) {
3,331✔
UNCOV
2599
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2600
  } else {
2601
    mstsInfo("end remove stream from maps, current stream num:%d", taosHashGetSize(mStreamMgmt.streamMap));
3,331✔
2602
  }
2603

2604
  return code;
3,331✔
2605
}
2606

2607
void msmUndeployStream(SMnode* pMnode, int64_t streamId, char* streamName) {
16,857✔
2608
  int32_t code = TSDB_CODE_SUCCESS;
16,857✔
2609
  int32_t lino = 0;
16,857✔
2610

2611
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
16,857✔
2612
  if (0 == active || MND_STM_STATE_NORMAL != state) {
16,857✔
UNCOV
2613
    mstsError("stream mgmt not available since active:%d state:%d", active, state);
×
2614
    return;
×
2615
  }
2616

2617
  SStmStatus* pStream = (SStmStatus*)taosHashAcquire(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
16,857✔
2618
  if (NULL == pStream) {
16,857✔
2619
    mstsInfo("stream %s already not in streamMap", streamName);
384✔
2620
    goto _exit;
384✔
2621
  }
2622

2623
  atomic_store_8(&pStream->stopped, 2);
16,473✔
2624

2625
  mstsInfo("set stream %s stopped by user", streamName);
16,473✔
2626

UNCOV
2627
_exit:
×
2628

2629
  taosHashRelease(mStreamMgmt.streamMap, pStream);
16,857✔
2630

2631
  if (code) {
16,857✔
UNCOV
2632
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2633
  }
2634

2635
  return;
16,857✔
2636
}
2637

2638
int32_t msmRecalcStream(SMnode* pMnode, int64_t streamId, STimeWindow* timeRange) {
6,733✔
2639
  int32_t code = TSDB_CODE_SUCCESS;
6,733✔
2640
  int32_t lino = 0;
6,733✔
2641

2642
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
6,733✔
2643
  if (0 == active || MND_STM_STATE_NORMAL != state) {
6,733✔
UNCOV
2644
    mstsError("stream mgmt not available since active:%d state:%d", active, state);
×
2645
    return TSDB_CODE_MND_STREAM_NOT_AVAILABLE;
×
2646
  }
2647

2648
  SStmStatus* pStream = (SStmStatus*)taosHashAcquire(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
6,733✔
2649
  if (NULL == pStream || !STREAM_IS_RUNNING(pStream)) {
6,733✔
UNCOV
2650
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
2651
    mstsInfo("stream still not in streamMap, streamRemains:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
2652
    goto _exit;
×
2653
  }
2654

2655
  TAOS_CHECK_EXIT(mstAppendNewRecalcRange(streamId, pStream, timeRange));
6,733✔
2656

2657
_exit:
6,733✔
2658

2659
  taosHashRelease(mStreamMgmt.streamMap, pStream);
6,733✔
2660

2661
  if (code) {
6,733✔
UNCOV
2662
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2663
  }
2664

2665
  return code;
6,733✔
2666
}
2667

2668
static void msmHandleStreamActions(SStmGrpCtx* pCtx) {
45,716✔
2669
  int32_t code = TSDB_CODE_SUCCESS;
45,716✔
2670
  int32_t lino = 0;
45,716✔
2671
  SStmQNode* pQNode = NULL;
45,716✔
2672

2673
  while (mndStreamActionDequeue(mStreamMgmt.actionQ, &pQNode)) {
253,111✔
2674
    switch (pQNode->type) {
207,395✔
2675
      case STREAM_ACT_DEPLOY:
207,395✔
2676
        if (pQNode->streamAct) {
207,395✔
2677
          mstDebug("start to handle stream deploy action");
204,803✔
2678
          TAOS_CHECK_EXIT(msmLaunchStreamDeployAction(pCtx, &pQNode->action.stream));
204,803✔
2679
        } else {
2680
          mstDebug("start to handle task deploy action");
2,592✔
2681
          TAOS_CHECK_EXIT(msmLaunchTaskDeployAction(pCtx, &pQNode->action.task));
2,592✔
2682
        }
2683
        break;
207,395✔
UNCOV
2684
      default:
×
2685
        break;
×
2686
    }
2687
  }
2688

2689
_exit:
45,716✔
2690

2691
  if (code) {
45,716✔
UNCOV
2692
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2693
  }
2694
}
45,716✔
2695

UNCOV
2696
void msmStopAllStreamsByGrant(int32_t errCode) {
×
2697
  SStmStatus* pStatus = NULL;
×
2698
  void* pIter = NULL;
×
2699
  int64_t streamId = 0;
×
2700
  
2701
  while (true) {
UNCOV
2702
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
×
2703
    if (NULL == pIter) {
×
2704
      break;
×
2705
    }
2706

UNCOV
2707
    pStatus = (SStmStatus*)pIter;
×
2708

UNCOV
2709
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
2710
    atomic_store_8(&pStatus->stopped, 4);
×
2711

UNCOV
2712
    mstsInfo("set stream stopped since %s", tstrerror(errCode));
×
2713
  }
UNCOV
2714
}
×
2715

UNCOV
2716
int32_t msmHandleGrantExpired(SMnode *pMnode, int32_t errCode) {
×
2717
  mstInfo("stream grant expired");
×
2718

UNCOV
2719
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
×
2720
    mstWarn("mnode stream is NOT active, ignore handling");
×
2721
    return errCode;
×
2722
  }
2723

UNCOV
2724
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, true);
×
2725

UNCOV
2726
  msmStopAllStreamsByGrant(errCode);
×
2727

UNCOV
2728
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
×
2729
  
UNCOV
2730
  return errCode;
×
2731
}
2732

2733
static int32_t msmInitStreamDeploy(SStmStreamDeploy* pStream, SStmTaskDeploy* pDeploy) {
1,444,169✔
2734
  int32_t code = TSDB_CODE_SUCCESS;
1,444,169✔
2735
  int32_t lino = 0;
1,444,169✔
2736
  int64_t streamId = pDeploy->task.streamId;
1,444,169✔
2737
  
2738
  switch (pDeploy->task.type) {
1,444,169✔
2739
    case STREAM_READER_TASK:
607,302✔
2740
      if (NULL == pStream->readerTasks) {
607,302✔
2741
        pStream->streamId = streamId;
266,904✔
2742
        pStream->readerTasks = taosArrayInit(20, sizeof(SStmTaskDeploy));
266,904✔
2743
        TSDB_CHECK_NULL(pStream->readerTasks, code, lino, _exit, terrno);
266,904✔
2744
      }
2745
      
2746
      TSDB_CHECK_NULL(taosArrayPush(pStream->readerTasks, pDeploy), code, lino, _exit, terrno);
1,214,604✔
2747
      break;
607,302✔
2748
    case STREAM_TRIGGER_TASK:
203,336✔
2749
      pStream->streamId = streamId;
203,336✔
2750
      pStream->triggerTask = taosMemoryMalloc(sizeof(SStmTaskDeploy));
203,336✔
2751
      TSDB_CHECK_NULL(pStream->triggerTask, code, lino, _exit, terrno);
203,336✔
2752
      memcpy(pStream->triggerTask, pDeploy, sizeof(SStmTaskDeploy));
203,336✔
2753
      break;
203,336✔
2754
    case STREAM_RUNNER_TASK:
633,531✔
2755
      if (NULL == pStream->runnerTasks) {
633,531✔
2756
        pStream->streamId = streamId;
210,220✔
2757
        pStream->runnerTasks = taosArrayInit(20, sizeof(SStmTaskDeploy));
210,220✔
2758
        TSDB_CHECK_NULL(pStream->runnerTasks, code, lino, _exit, terrno);
210,220✔
2759
      }      
2760
      TSDB_CHECK_NULL(taosArrayPush(pStream->runnerTasks, pDeploy), code, lino, _exit, terrno);
1,267,062✔
2761
      break;
633,531✔
UNCOV
2762
    default:
×
2763
      break;
×
2764
  }
2765

2766
_exit:
1,444,169✔
2767

2768
  if (code) {
1,444,169✔
UNCOV
2769
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2770
  }
2771

2772
  return code;
1,444,169✔
2773
}
2774

2775
static int32_t msmGrpAddDeployTask(SHashObj* pHash, SStmTaskDeploy* pDeploy) {
1,444,169✔
2776
  int32_t code = TSDB_CODE_SUCCESS;
1,444,169✔
2777
  int32_t lino = 0;
1,444,169✔
2778
  int64_t streamId = pDeploy->task.streamId;
1,444,169✔
2779
  SStreamTask* pTask = &pDeploy->task;
1,444,169✔
2780
  SStmStreamDeploy streamDeploy = {0};
1,444,169✔
2781
  SStmStreamDeploy* pStream = NULL;
1,444,169✔
2782
   
2783
  while (true) {
2784
    pStream = taosHashAcquire(pHash, &streamId, sizeof(streamId));
1,444,169✔
2785
    if (NULL == pStream) {
1,444,169✔
2786
      TAOS_CHECK_EXIT(msmInitStreamDeploy(&streamDeploy, pDeploy));
285,226✔
2787
      code = taosHashPut(pHash, &streamId, sizeof(streamId), &streamDeploy, sizeof(streamDeploy));
285,226✔
2788
      if (TSDB_CODE_SUCCESS == code) {
285,226✔
2789
        goto _exit;
285,226✔
2790
      }
2791

UNCOV
2792
      if (TSDB_CODE_DUP_KEY != code) {
×
2793
        goto _exit;
×
2794
      }    
2795

UNCOV
2796
      tFreeSStmStreamDeploy(&streamDeploy);
×
2797
      continue;
×
2798
    }
2799

2800
    TAOS_CHECK_EXIT(msmInitStreamDeploy(pStream, pDeploy));
1,158,943✔
2801
    
2802
    break;
1,158,943✔
2803
  }
2804
  
2805
_exit:
1,444,169✔
2806

2807
  taosHashRelease(pHash, pStream);
1,444,169✔
2808

2809
  if (code) {
1,444,169✔
UNCOV
2810
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2811
  } else {
2812
    msttDebug("task added to GRP deployMap, taskIdx:%d", pTask->taskIdx);
1,444,169✔
2813
  }
2814

2815
  return code;
1,444,169✔
2816
}
2817

2818

2819
int32_t msmGrpAddDeployTasks(SHashObj* pHash, SArray* pTasks, int32_t* deployed) {
226,928✔
2820
  int32_t code = TSDB_CODE_SUCCESS;
226,928✔
2821
  int32_t lino = 0;
226,928✔
2822
  int32_t taskNum = taosArrayGetSize(pTasks);
226,928✔
2823

2824
  for (int32_t i = 0; i < taskNum; ++i) {
1,672,541✔
2825
    SStmTaskToDeployExt* pExt = taosArrayGet(pTasks, i);
1,445,613✔
2826
    if (pExt->deployed) {
1,445,613✔
2827
      continue;
1,444✔
2828
    }
2829

2830
    TAOS_CHECK_EXIT(msmGrpAddDeployTask(pHash, &pExt->deploy));
1,444,169✔
2831
    pExt->deployed = true;
1,444,169✔
2832

2833
    (void)atomic_add_fetch_32(deployed, 1);
1,444,169✔
2834
  }
2835

2836
_exit:
226,928✔
2837

2838
  if (code) {
226,928✔
UNCOV
2839
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2840
  }
2841

2842
  return code;
226,928✔
2843
}
2844

2845
int32_t msmGrpAddDeployVgTasks(SStmGrpCtx* pCtx) {
64,429✔
2846
  int32_t code = TSDB_CODE_SUCCESS;
64,429✔
2847
  int32_t lino = 0;
64,429✔
2848
  int32_t vgNum = taosArrayGetSize(pCtx->pReq->pVgLeaders);
64,429✔
2849
  SStmVgTasksToDeploy* pVg = NULL;
64,429✔
2850
  //int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pCtx->pReq->streamGId);
2851

2852
  mstDebug("start to add stream vgroup tasks deploy");
64,429✔
2853
  
2854
  for (int32_t i = 0; i < vgNum; ++i) {
428,872✔
2855
    int32_t* vgId = taosArrayGet(pCtx->pReq->pVgLeaders, i);
364,443✔
2856

2857
    msmUpdateVgroupUpTs(pCtx, *vgId);
364,443✔
2858

2859
    pVg = taosHashAcquire(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId));
364,443✔
2860
    if (NULL == pVg) {
364,443✔
2861
      continue;
234,114✔
2862
    }
2863

2864
    if (taosRTryLockLatch(&pVg->lock)) {
130,329✔
UNCOV
2865
      continue;
×
2866
    }
2867
    
2868
    if (atomic_load_32(&pVg->deployed) == taosArrayGetSize(pVg->taskList)) {
130,329✔
UNCOV
2869
      taosRUnLockLatch(&pVg->lock);
×
2870
      continue;
×
2871
    }
2872
    
2873
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pVg->taskList, &pVg->deployed));
130,329✔
2874
    taosRUnLockLatch(&pVg->lock);
130,329✔
2875
  }
2876

2877
_exit:
64,429✔
2878

2879
  if (code) {
64,429✔
UNCOV
2880
    if (pVg) {
×
2881
      taosRUnLockLatch(&pVg->lock);
×
2882
    }
2883

UNCOV
2884
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2885
  }
2886

2887
  return code;
64,429✔
2888
}
2889

2890
int32_t msmGrpAddDeploySnodeTasks(SStmGrpCtx* pCtx) {
79,253✔
2891
  int32_t code = TSDB_CODE_SUCCESS;
79,253✔
2892
  int32_t lino = 0;
79,253✔
2893
  SStmSnodeTasksDeploy* pSnode = NULL;
79,253✔
2894
  SStreamHbMsg* pReq = pCtx->pReq;
79,253✔
2895

2896
  mstDebug("start to add stream snode tasks deploy");
79,253✔
2897
  
2898
  pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &pReq->snodeId, sizeof(pReq->snodeId));
79,253✔
2899
  if (NULL == pSnode) {
79,253✔
2900
    return TSDB_CODE_SUCCESS;
29,264✔
2901
  }
2902

2903
  (void)mstWaitLock(&pSnode->lock, false);
49,989✔
2904
  
2905
  if (atomic_load_32(&pSnode->triggerDeployed) < taosArrayGetSize(pSnode->triggerList)) {
49,989✔
2906
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pSnode->triggerList, &pSnode->triggerDeployed));
46,610✔
2907
  }
2908

2909
  if (atomic_load_32(&pSnode->runnerDeployed) < taosArrayGetSize(pSnode->runnerList)) {
49,989✔
2910
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pSnode->runnerList, &pSnode->runnerDeployed));
49,989✔
2911
  }
2912
  
2913
  taosWUnLockLatch(&pSnode->lock);
49,989✔
2914

2915
_exit:
49,989✔
2916

2917
  if (code) {
49,989✔
UNCOV
2918
    if (pSnode) {
×
2919
      taosWUnLockLatch(&pSnode->lock);
×
2920
    }
2921

UNCOV
2922
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2923
  }
2924

2925
  return code;
49,989✔
2926
}
2927

2928
int32_t msmUpdateStreamLastActTs(int64_t streamId, int64_t currTs) {
622,262✔
2929
  int32_t code = TSDB_CODE_SUCCESS;
622,262✔
2930
  int32_t lino = 0;
622,262✔
2931
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
622,262✔
2932
  if (NULL == pStatus) {
622,262✔
UNCOV
2933
    mstsWarn("stream already not exists in streamMap, mapSize:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
2934
    return TSDB_CODE_SUCCESS;
×
2935
  }
2936
  
2937
  pStatus->lastActionTs = currTs;
622,262✔
2938

2939
_exit:
622,262✔
2940

2941
  if (code) {
622,262✔
UNCOV
2942
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2943
  }
2944

2945
  return code;
622,262✔
2946
}
2947

2948
int32_t msmRspAddStreamsDeploy(SStmGrpCtx* pCtx) {
68,299✔
2949
  int32_t code = TSDB_CODE_SUCCESS;
68,299✔
2950
  int32_t lino = 0;
68,299✔
2951
  int32_t streamNum = taosHashGetSize(pCtx->deployStm);
68,299✔
2952
  void* pIter = NULL;
68,299✔
2953

2954
  mstDebug("start to add group %d deploy streams, streamNum:%d", pCtx->pReq->streamGId, taosHashGetSize(pCtx->deployStm));
68,299✔
2955
  
2956
  pCtx->pRsp->deploy.streamList = taosArrayInit(streamNum, sizeof(SStmStreamDeploy));
68,299✔
2957
  TSDB_CHECK_NULL(pCtx->pRsp->deploy.streamList, code, lino, _exit, terrno);
68,299✔
2958

2959
  while (1) {
285,226✔
2960
    pIter = taosHashIterate(pCtx->deployStm, pIter);
353,525✔
2961
    if (pIter == NULL) {
353,525✔
2962
      break;
68,299✔
2963
    }
2964
    
2965
    SStmStreamDeploy *pDeploy = (SStmStreamDeploy *)pIter;
285,226✔
2966
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->deploy.streamList, pDeploy), code, lino, _exit, terrno);
570,452✔
2967

2968
    int64_t streamId = pDeploy->streamId;
285,226✔
2969
    mstsDebug("stream DEPLOY added to dnode %d hb rsp, readerTasks:%zu, triggerTask:%d, runnerTasks:%zu", 
285,226✔
2970
        pCtx->pReq->dnodeId, taosArrayGetSize(pDeploy->readerTasks), pDeploy->triggerTask ? 1 : 0, taosArrayGetSize(pDeploy->runnerTasks));
2971

2972
    mstClearSStmStreamDeploy(pDeploy);
285,226✔
2973
    
2974
    TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(pDeploy->streamId, pCtx->currTs));
285,226✔
2975
  }
2976
  
2977
_exit:
68,299✔
2978

2979
  if (pIter) {
68,299✔
UNCOV
2980
    taosHashCancelIterate(pCtx->deployStm, pIter);
×
2981
  }
2982

2983
  if (code) {
68,299✔
UNCOV
2984
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2985
  }
2986
  
2987
  return code;
68,299✔
2988
}
2989

2990
void msmCleanDeployedVgTasks(SArray* pVgLeaders) {
64,429✔
2991
  int32_t code = TSDB_CODE_SUCCESS;
64,429✔
2992
  int32_t lino = 0;
64,429✔
2993
  int32_t vgNum = taosArrayGetSize(pVgLeaders);
64,429✔
2994
  SStmVgTasksToDeploy* pVg = NULL;
64,429✔
2995
  
2996
  for (int32_t i = 0; i < vgNum; ++i) {
428,872✔
2997
    int32_t* vgId = taosArrayGet(pVgLeaders, i);
364,443✔
2998
    pVg = taosHashAcquire(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId));
364,443✔
2999
    if (NULL == pVg) {
364,443✔
3000
      continue;
234,114✔
3001
    }
3002

3003
    if (taosWTryLockLatch(&pVg->lock)) {
130,329✔
UNCOV
3004
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
×
3005
      continue;
×
3006
    }
3007
    
3008
    if (atomic_load_32(&pVg->deployed) <= 0) {
130,329✔
UNCOV
3009
      taosWUnLockLatch(&pVg->lock);
×
3010
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
×
3011
      continue;
×
3012
    }
3013

3014
    int32_t taskNum = taosArrayGetSize(pVg->taskList);
130,329✔
3015
    if (atomic_load_32(&pVg->deployed) == taskNum) {
130,329✔
3016
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeployVgTaskNum, taskNum);
130,329✔
3017
      taosArrayDestroyEx(pVg->taskList, mstDestroySStmTaskToDeployExt);
130,329✔
3018
      pVg->taskList = NULL;
130,329✔
3019
      TAOS_UNUSED(taosHashRemove(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId)));
130,329✔
3020
      taosWUnLockLatch(&pVg->lock);
130,329✔
3021
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
130,329✔
3022
      continue;
130,329✔
3023
    }
3024

UNCOV
3025
    for (int32_t m = taskNum - 1; m >= 0; --m) {
×
UNCOV
3026
      SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, m);
×
UNCOV
3027
      if (!pExt->deployed) {
×
UNCOV
3028
        continue;
×
3029
      }
3030

UNCOV
3031
      mstDestroySStmTaskToDeployExt(pExt);
×
3032

UNCOV
3033
      taosArrayRemove(pVg->taskList, m);
×
UNCOV
3034
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeployVgTaskNum, 1);
×
3035
    }
UNCOV
3036
    atomic_store_32(&pVg->deployed, 0);
×
UNCOV
3037
    taosWUnLockLatch(&pVg->lock);
×
UNCOV
3038
    taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
×
3039
  }
3040

3041
_exit:
64,429✔
3042

3043
  if (code) {
64,429✔
UNCOV
3044
    if (pVg) {
×
3045
      taosWUnLockLatch(&pVg->lock);
×
3046
    }
3047

UNCOV
3048
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3049
  }
3050
}
64,429✔
3051

3052
void msmCleanDeployedSnodeTasks (int32_t snodeId) {
97,376✔
3053
  if (!GOT_SNODE(snodeId)) {
97,376✔
3054
    return;
18,123✔
3055
  }
3056
  
3057
  int32_t code = TSDB_CODE_SUCCESS;
79,253✔
3058
  SStmSnodeTasksDeploy* pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &snodeId, sizeof(snodeId));
79,253✔
3059
  if (NULL == pSnode) {
79,253✔
3060
    return;
29,264✔
3061
  }
3062

3063
  if (taosWTryLockLatch(&pSnode->lock)) {
49,989✔
UNCOV
3064
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
×
3065
    return;
×
3066
  }
3067

3068
  int32_t triggerNum = taosArrayGetSize(pSnode->triggerList);
49,989✔
3069
  int32_t runnerNum = taosArrayGetSize(pSnode->runnerList);
49,989✔
3070
  
3071
  if (atomic_load_32(&pSnode->triggerDeployed) <= 0 && atomic_load_32(&pSnode->runnerDeployed) <= 0) {
49,989✔
UNCOV
3072
    taosWUnLockLatch(&pSnode->lock);
×
UNCOV
3073
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
×
UNCOV
3074
    return;
×
3075
  }
3076

3077
  if (atomic_load_32(&pSnode->triggerDeployed) == triggerNum) {
49,989✔
3078
    (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, triggerNum);
49,628✔
3079
    taosArrayDestroyEx(pSnode->triggerList, mstDestroySStmTaskToDeployExt);
49,628✔
3080
    pSnode->triggerList = NULL;
49,628✔
3081
  }
3082

3083
  if (atomic_load_32(&pSnode->runnerDeployed) == runnerNum) {
49,989✔
3084
    (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, runnerNum);
49,267✔
3085
    taosArrayDestroyEx(pSnode->runnerList, mstDestroySStmTaskToDeployExt);
49,267✔
3086
    pSnode->runnerList = NULL;
49,267✔
3087
  }
3088

3089
  if (NULL == pSnode->triggerList && NULL == pSnode->runnerList) {
49,989✔
3090
    TAOS_UNUSED(taosHashRemove(mStreamMgmt.toDeploySnodeMap, &snodeId, sizeof(snodeId)));
49,267✔
3091
    taosWUnLockLatch(&pSnode->lock);
49,267✔
3092
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
49,267✔
3093
    return;
49,267✔
3094
  }
3095

3096
  if (atomic_load_32(&pSnode->triggerDeployed) > 0 && pSnode->triggerList) {
722✔
3097
    for (int32_t m = triggerNum - 1; m >= 0; --m) {
1,805✔
3098
      SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, m);
1,444✔
3099
      if (!pExt->deployed) {
1,444✔
UNCOV
3100
        continue;
×
3101
      }
3102

3103
      mstDestroySStmTaskToDeployExt(pExt);
1,444✔
3104
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
1,444✔
3105
      taosArrayRemove(pSnode->triggerList, m);
1,444✔
3106
    }
3107
    
3108
    pSnode->triggerDeployed = 0;
361✔
3109
  }
3110

3111
  if (atomic_load_32(&pSnode->runnerDeployed) > 0 && pSnode->runnerList) {
722✔
3112
    for (int32_t m = runnerNum - 1; m >= 0; --m) {
5,054✔
3113
      SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, m);
4,332✔
3114
      if (!pExt->deployed) {
4,332✔
UNCOV
3115
        continue;
×
3116
      }
3117

3118
      mstDestroySStmTaskToDeployExt(pExt);
4,332✔
3119
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
4,332✔
3120
      taosArrayRemove(pSnode->runnerList, m);
4,332✔
3121
    }
3122
    
3123
    pSnode->runnerDeployed = 0;
722✔
3124
  }
3125
  
3126
  taosWUnLockLatch(&pSnode->lock);
722✔
3127
  taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
722✔
3128
}
3129

3130
void msmClearStreamToDeployMaps(SStreamHbMsg* pHb) {
15,475,504✔
3131
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
15,475,504✔
3132
    msmCleanDeployedVgTasks(pHb->pVgLeaders);
64,429✔
3133
  }
3134

3135
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0) {
15,475,504✔
3136
    msmCleanDeployedSnodeTasks(pHb->snodeId);
97,376✔
3137
  }
3138
}
15,475,504✔
3139

3140
void msmCleanStreamGrpCtx(SStreamHbMsg* pHb) {
15,475,504✔
3141
  int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pHb->streamGId);
15,475,504✔
3142
  if (mStreamMgmt.tCtx) {
15,475,504✔
3143
    taosHashClear(mStreamMgmt.tCtx[tidx].actionStm[pHb->streamGId]);
15,280,709✔
3144
    taosHashClear(mStreamMgmt.tCtx[tidx].deployStm[pHb->streamGId]);
15,280,709✔
3145
  }
3146
}
15,475,504✔
3147

3148
int32_t msmGrpAddActionStart(SHashObj* pHash, int64_t streamId, SStmTaskId* pId) {
276,487✔
3149
  int32_t code = TSDB_CODE_SUCCESS;
276,487✔
3150
  int32_t lino = 0;
276,487✔
3151
  int32_t action = STREAM_ACT_START;
276,487✔
3152
  SStmAction *pAction = taosHashGet(pHash, &streamId, sizeof(streamId));
276,487✔
3153
  if (pAction) {
276,487✔
UNCOV
3154
    pAction->actions |= action;
×
3155
    pAction->start.triggerId = *pId;
×
3156
    mstsDebug("stream append START action, actions:%x", pAction->actions);
×
3157
  } else {
3158
    SStmAction newAction = {0};
276,487✔
3159
    newAction.actions = action;
276,487✔
3160
    newAction.start.triggerId = *pId;
276,487✔
3161
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
276,487✔
3162
    mstsDebug("stream add START action, actions:%x", newAction.actions);
276,487✔
3163
  }
3164

3165
_exit:
276,487✔
3166

3167
  if (code) {
276,487✔
UNCOV
3168
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3169
  }
3170

3171
  return code;
276,487✔
3172
}
3173

UNCOV
3174
int32_t msmGrpAddActionUpdateTrigger(SHashObj* pHash, int64_t streamId) {
×
3175
  int32_t code = TSDB_CODE_SUCCESS;
×
3176
  int32_t lino = 0;
×
3177
  int32_t action = STREAM_ACT_UPDATE_TRIGGER;
×
3178
  
UNCOV
3179
  SStmAction *pAction = taosHashGet(pHash, &streamId, sizeof(streamId));
×
3180
  if (pAction) {
×
3181
    pAction->actions |= action;
×
3182
    mstsDebug("stream append UPDATE_TRIGGER action, actions:%x", pAction->actions);
×
3183
  } else {
UNCOV
3184
    SStmAction newAction = {0};
×
3185
    newAction.actions = action;
×
3186
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
×
3187
    mstsDebug("stream add UPDATE_TRIGGER action, actions:%x", newAction.actions);
×
3188
  }
3189

UNCOV
3190
_exit:
×
3191

UNCOV
3192
  if (code) {
×
3193
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3194
  }
3195

UNCOV
3196
  return code;
×
3197
}
3198

3199

3200

3201
int32_t msmGrpAddActionUndeploy(SStmGrpCtx* pCtx, int64_t streamId, SStreamTask* pTask) {
60,549✔
3202
  int32_t code = TSDB_CODE_SUCCESS;
60,549✔
3203
  int32_t lino = 0;
60,549✔
3204
  int32_t action = STREAM_ACT_UNDEPLOY;
60,549✔
3205
  bool    dropped = false;
60,549✔
3206

3207
  TAOS_CHECK_EXIT(mstIsStreamDropped(pCtx->pMnode, streamId, &dropped));
60,549✔
3208
  mstsDebug("stream dropped: %d", dropped);
60,549✔
3209
  
3210
  SStmAction *pAction = taosHashGet(pCtx->actionStm, &streamId, sizeof(streamId));
60,549✔
3211
  if (pAction) {
60,549✔
3212
    pAction->actions |= action;
36,544✔
3213
    if (NULL == pAction->undeploy.taskList) {
36,544✔
UNCOV
3214
      pAction->undeploy.taskList = taosArrayInit(pCtx->taskNum, POINTER_BYTES);
×
3215
      TSDB_CHECK_NULL(pAction->undeploy.taskList, code, lino, _exit, terrno);
×
3216
    }
3217

3218
    TSDB_CHECK_NULL(taosArrayPush(pAction->undeploy.taskList, &pTask), code, lino, _exit, terrno);
73,088✔
3219
    if (pAction->undeploy.doCheckpoint) {
36,544✔
3220
      pAction->undeploy.doCheckpoint = dropped ? false : true;
16,239✔
3221
    }
3222
    if (!pAction->undeploy.doCleanup) {
36,544✔
3223
      pAction->undeploy.doCleanup = dropped ? true : false;
16,239✔
3224
    }
3225
    
3226
    msttDebug("task append UNDEPLOY action[%d,%d], actions:%x", pAction->undeploy.doCheckpoint, pAction->undeploy.doCleanup, pAction->actions);
36,544✔
3227
  } else {
3228
    SStmAction newAction = {0};
24,005✔
3229
    newAction.actions = action;
24,005✔
3230
    newAction.undeploy.doCheckpoint = dropped ? false : true;
24,005✔
3231
    newAction.undeploy.doCleanup = dropped ? true : false;
24,005✔
3232
    newAction.undeploy.taskList = taosArrayInit(pCtx->taskNum, POINTER_BYTES);
24,005✔
3233
    TSDB_CHECK_NULL(newAction.undeploy.taskList, code, lino, _exit, terrno);
24,005✔
3234
    TSDB_CHECK_NULL(taosArrayPush(newAction.undeploy.taskList, &pTask), code, lino, _exit, terrno);
48,010✔
3235
    TAOS_CHECK_EXIT(taosHashPut(pCtx->actionStm, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
24,005✔
3236
    
3237
    msttDebug("task add UNDEPLOY action[%d,%d]", newAction.undeploy.doCheckpoint, newAction.undeploy.doCleanup);
24,005✔
3238
  }
3239

3240
_exit:
60,549✔
3241

3242
  if (code) {
60,549✔
UNCOV
3243
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3244
  }
3245

3246
  return code;
60,549✔
3247
}
3248

3249
int32_t msmGrpAddActionRecalc(SStmGrpCtx* pCtx, int64_t streamId, SArray* recalcList) {
6,300✔
3250
  int32_t code = TSDB_CODE_SUCCESS;
6,300✔
3251
  int32_t lino = 0;
6,300✔
3252
  int32_t action = STREAM_ACT_RECALC;
6,300✔
3253
  SStmAction newAction = {0};
6,300✔
3254
  
3255
  SStmAction *pAction = taosHashGet(pCtx->actionStm, &streamId, sizeof(streamId));
6,300✔
3256
  if (pAction) {
6,300✔
UNCOV
3257
    pAction->actions |= action;
×
3258
    pAction->recalc.recalcList = recalcList;
×
3259

UNCOV
3260
    mstsDebug("stream append recalc action, listSize:%d, actions:%x", (int32_t)taosArrayGetSize(recalcList), pAction->actions);
×
3261
  } else {
3262
    newAction.actions = action;
6,300✔
3263
    newAction.recalc.recalcList = recalcList;
6,300✔
3264
    
3265
    TAOS_CHECK_EXIT(taosHashPut(pCtx->actionStm, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
6,300✔
3266
    
3267
    mstsDebug("stream add recalc action, listSize:%d", (int32_t)taosArrayGetSize(recalcList));
6,300✔
3268
  }
3269

3270
_exit:
6,300✔
3271

3272
  if (code) {
6,300✔
UNCOV
3273
    mstDestroySStmAction(&newAction);
×
3274
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3275
  }
3276

3277
  return code;
6,300✔
3278
}
3279

3280
bool msmCheckStreamStartCond(int64_t streamId, int32_t snodeId) {
364,607✔
3281
  SStmStatus* pStream = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
364,607✔
3282
  if (NULL == pStream) {
364,607✔
UNCOV
3283
    return false;
×
3284
  }
3285

3286
  if (pStream->triggerTask->id.nodeId != snodeId || STREAM_STATUS_INIT != pStream->triggerTask->status) {
364,607✔
UNCOV
3287
    return false;
×
3288
  }
3289

3290
  int32_t readerNum = taosArrayGetSize(pStream->trigReaders);
364,607✔
3291
  for (int32_t i = 0; i < readerNum; ++i) {
806,515✔
3292
    SStmTaskStatus* pStatus = taosArrayGet(pStream->trigReaders, i);
441,908✔
3293
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
441,908✔
UNCOV
3294
      return false;
×
3295
    }
3296
  }
3297

3298
  readerNum = taosArrayGetSize(pStream->trigOReaders);
364,607✔
3299
  for (int32_t i = 0; i < readerNum; ++i) {
430,497✔
3300
    SStmTaskStatus* pStatus = taosArrayGet(pStream->trigOReaders, i);
65,890✔
3301
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
65,890✔
UNCOV
3302
      return false;
×
3303
    }
3304
  }
3305

3306
  readerNum = MST_LIST_SIZE(pStream->calcReaders);
364,607✔
3307
  SListNode* pNode = listHead(pStream->calcReaders);
364,607✔
3308
  for (int32_t i = 0; i < readerNum; ++i) {
1,021,943✔
3309
    SStmTaskStatus* pStatus = (SStmTaskStatus*)pNode->data;
657,336✔
3310
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
657,336✔
UNCOV
3311
      return false;
×
3312
    }
3313
    pNode = TD_DLIST_NODE_NEXT(pNode);
657,336✔
3314
  }
3315

3316
  for (int32_t i = 0; i < pStream->runnerDeploys; ++i) {
1,180,997✔
3317
    int32_t runnerNum = taosArrayGetSize(pStream->runners[i]);
904,510✔
3318
    for (int32_t m = 0; m < runnerNum; ++m) {
1,754,962✔
3319
      SStmTaskStatus* pStatus = taosArrayGet(pStream->runners[i], m);
938,572✔
3320
      if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
938,572✔
3321
        return false;
88,120✔
3322
      }
3323
    }
3324
  }
3325
  
3326
  return true;
276,487✔
3327
}
3328

3329

3330
void msmHandleTaskAbnormalStatus(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pMsg, SStmTaskStatus* pTaskStatus) {
11,488,408✔
3331
  int32_t code = TSDB_CODE_SUCCESS;
11,488,408✔
3332
  int32_t lino = 0;
11,488,408✔
3333
  int32_t action = 0;
11,488,408✔
3334
  int64_t streamId = pMsg->streamId;
11,488,408✔
3335
  SStreamTask* pTask = (SStreamTask*)pMsg;
11,488,408✔
3336
  int8_t  stopped = 0;
11,488,408✔
3337

3338
  msttDebug("start to handle task abnormal status %d", pTask->status);
11,488,408✔
3339
  
3340
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
11,488,408✔
3341
  if (NULL == pStatus) {
11,488,408✔
UNCOV
3342
    msttInfo("stream no longer exists in streamMap, try to undeploy current task, idx:%d", pMsg->taskIdx);
×
3343
    TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
×
3344
    return;
72,203✔
3345
  }
3346

3347
  stopped = atomic_load_8(&pStatus->stopped);
11,488,408✔
3348
  if (stopped) {
11,488,408✔
UNCOV
3349
    msttInfo("stream stopped %d, try to undeploy current task, idx:%d", stopped, pMsg->taskIdx);
×
3350
    TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
×
3351
    return;
×
3352
  }
3353
  
3354
  switch (pMsg->status) {
11,488,408✔
3355
    case STREAM_STATUS_INIT:      
11,482,701✔
3356
      if (STREAM_TRIGGER_TASK != pMsg->type) {
11,482,701✔
3357
        msttTrace("task status is INIT and not trigger task, ignore it, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
10,941,056✔
3358
        return;
10,941,056✔
3359
      }
3360
      
3361
      if (INT64_MIN == pStatus->lastActionTs) {
541,645✔
UNCOV
3362
        msttDebug("task still not deployed, ignore it, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
×
3363
        return;
×
3364
      }
3365
      
3366
      if ((pCtx->currTs - pStatus->lastActionTs) < STREAM_ACT_MIN_DELAY_MSEC) {
541,645✔
3367
        msttDebug("task wait not enough between actions, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
177,038✔
3368
        return;
177,038✔
3369
      }
3370

3371
      if (STREAM_IS_RUNNING(pStatus)) {
364,607✔
UNCOV
3372
        msttDebug("stream already running, ignore status: %s", gStreamStatusStr[pTask->status]);
×
3373
      } else if (GOT_SNODE(pCtx->pReq->snodeId) && msmCheckStreamStartCond(streamId, pCtx->pReq->snodeId)) {
364,607✔
3374
        TAOS_CHECK_EXIT(msmGrpAddActionStart(pCtx->actionStm, streamId, &pStatus->triggerTask->id));
276,487✔
3375
      }
3376
      break;
364,607✔
3377
    case STREAM_STATUS_FAILED:
5,707✔
3378
      //STREAMTODO ADD ERRCODE HANDLE
3379
      msttInfo("task failed with error:%s, try to undeploy current task, idx:%d", tstrerror(pMsg->errorCode), pMsg->taskIdx);
5,707✔
3380
      TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
5,707✔
3381
      break;
5,707✔
UNCOV
3382
    default:
×
3383
      break;
×
3384
  }
3385

3386
_exit:
370,314✔
3387

3388
  if (code) {
370,314✔
UNCOV
3389
    msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
3390
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3391
  }
3392
}
3393

3394
void msmHandleStreamTaskErr(SStmGrpCtx* pCtx, EStmErrType err, SStmTaskStatusMsg* pStatus) {
54,842✔
3395
  int32_t code = TSDB_CODE_SUCCESS;
54,842✔
3396
  int32_t lino = 0;
54,842✔
3397
  SStreamTask* pTask = (SStreamTask*)pStatus;
54,842✔
3398
  int64_t streamId = pStatus->streamId;
54,842✔
3399

3400
  msttInfo("start to handle task error, type: %d", err);
54,842✔
3401

3402
  TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
54,842✔
3403

3404
_exit:
54,842✔
3405

3406
  if (code) {
54,842✔
3407
    // IGNORE STOP STREAM BY ERROR  
UNCOV
3408
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3409
  }
3410
}
54,842✔
3411

3412
void msmChkHandleTriggerOperations(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask, SStmTaskStatus* pStatus) {
4,143,328✔
3413
  int32_t code = TSDB_CODE_SUCCESS;
4,143,328✔
3414
  int32_t lino = 0;
4,143,328✔
3415
  SStmStatus* pStream = (SStmStatus*)pStatus->pStream;
4,143,328✔
3416

3417
  if (1 == atomic_val_compare_exchange_8(&pStream->triggerNeedUpdate, 1, 0)) {
4,143,328✔
UNCOV
3418
    TAOS_CHECK_EXIT(msmGrpAddActionUpdateTrigger(pCtx->actionStm, pTask->streamId));
×
3419
  }
3420
  
3421
  SArray* userRecalcList = NULL;
4,143,328✔
3422
  if (atomic_load_ptr(&pStream->userRecalcList)) {
4,143,328✔
3423
    taosWLockLatch(&pStream->userRecalcLock);
6,300✔
3424
    if (pStream->userRecalcList) {
6,300✔
3425
      userRecalcList = pStream->userRecalcList;
6,300✔
3426
      pStream->userRecalcList = NULL;
6,300✔
3427
    }
3428
    taosWUnLockLatch(&pStream->userRecalcLock);
6,300✔
3429
    
3430
    if (userRecalcList) {
6,300✔
3431
      TAOS_CHECK_EXIT(msmGrpAddActionRecalc(pCtx, pTask->streamId, userRecalcList));
6,300✔
3432
    }
3433
  }
3434

3435
  if (pTask->detailStatus >= 0 && pCtx->pReq->pTriggerStatus) {
4,143,328✔
3436
    (void)mstWaitLock(&pStatus->detailStatusLock, false);
2,071,565✔
3437
    if (NULL == pStatus->detailStatus) {
2,071,565✔
3438
      pStatus->detailStatus = taosMemoryCalloc(1, sizeof(SSTriggerRuntimeStatus));
202,543✔
3439
      if (NULL == pStatus->detailStatus) {
202,543✔
UNCOV
3440
        taosWUnLockLatch(&pStatus->detailStatusLock);
×
UNCOV
3441
        TSDB_CHECK_NULL(pStatus->detailStatus, code, lino, _exit, terrno);
×
3442
      }
3443
    }
3444
    
3445
    memcpy(pStatus->detailStatus, taosArrayGet(pCtx->pReq->pTriggerStatus, pTask->detailStatus), sizeof(SSTriggerRuntimeStatus));
2,071,565✔
3446
    taosWUnLockLatch(&pStatus->detailStatusLock);
2,071,565✔
3447
  }
3448

3449
_exit:
2,071,763✔
3450

3451
  if (code) {
4,143,328✔
3452
    // IGNORE STOP STREAM BY ERROR
UNCOV
3453
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3454
  }
3455
}
4,143,328✔
3456

3457
int32_t msmNormalHandleStatusUpdate(SStmGrpCtx* pCtx) {
1,380,910✔
3458
  int32_t code = TSDB_CODE_SUCCESS;
1,380,910✔
3459
  int32_t lino = 0;
1,380,910✔
3460
  int32_t num = taosArrayGetSize(pCtx->pReq->pStreamStatus);
1,380,910✔
3461

3462
  mstDebug("NORMAL: start to handle stream group %d tasks status, taskNum:%d", pCtx->pReq->streamGId, num);
1,380,910✔
3463

3464
  for (int32_t i = 0; i < num; ++i) {
31,395,380✔
3465
    SStmTaskStatusMsg* pTask = taosArrayGet(pCtx->pReq->pStreamStatus, i);
30,014,470✔
3466
    msttDebug("task status %s got on dnode %d, taskIdx:%d", gStreamStatusStr[pTask->status], pCtx->pReq->dnodeId, pTask->taskIdx);
30,014,470✔
3467
    
3468
    SStmTaskStatus** ppStatus = taosHashGet(mStreamMgmt.taskMap, &pTask->streamId, sizeof(pTask->streamId) + sizeof(pTask->taskId));
30,014,470✔
3469
    if (NULL == ppStatus) {
30,014,470✔
3470
      msttWarn("task no longer exists in taskMap, will try to undeploy current task, taskIdx:%d", pTask->taskIdx);
13,416✔
3471
      msmHandleStreamTaskErr(pCtx, STM_ERR_TASK_NOT_EXISTS, pTask);
13,416✔
3472
      continue;
13,416✔
3473
    }
3474

3475
    SStmStatus* pStream = (SStmStatus*)(*ppStatus)->pStream;
30,001,054✔
3476
    int8_t stopped = atomic_load_8(&pStream->stopped);
30,001,054✔
3477
    if (stopped) {
30,001,054✔
3478
      msttWarn("stream already stopped %d, will try to undeploy current task, taskIdx:%d", stopped, pTask->taskIdx);
41,426✔
3479
      msmHandleStreamTaskErr(pCtx, STM_ERR_STREAM_STOPPED, pTask);
41,426✔
3480
      continue;
41,426✔
3481
    }
3482

3483
    if ((pTask->seriousId != (*ppStatus)->id.seriousId) || (pTask->nodeId != (*ppStatus)->id.nodeId)) {
29,959,628✔
3484
      msttInfo("task mismatch with it in taskMap, will try to rm it, current seriousId:%" PRId64 ", nodeId:%d", 
×
3485
          (*ppStatus)->id.seriousId, (*ppStatus)->id.nodeId);
3486
          
NEW
3487
      msmHandleStreamTaskErr(pCtx, STM_ERR_TASK_NOT_EXISTS, pTask);
×
UNCOV
3488
      continue;
×
3489
    }
3490

3491
    if ((*ppStatus)->status != pTask->status) {
29,959,628✔
3492
      if (STREAM_STATUS_RUNNING == pTask->status) {
2,502,115✔
3493
        (*ppStatus)->runningStartTs = pCtx->currTs;
1,060,697✔
3494
      } else if (MST_IS_RUNNER_GETTING_READY(pTask) && STREAM_IS_REDEPLOY_RUNNER((*ppStatus)->flags)) {
1,441,418✔
UNCOV
3495
        if (pStream->triggerTask) {
×
3496
          atomic_store_8(&pStream->triggerNeedUpdate, 1);
×
3497
        }
3498
        
UNCOV
3499
        STREAM_CLR_FLAG((*ppStatus)->flags, STREAM_FLAG_REDEPLOY_RUNNER);
×
3500
      }
3501
    }
3502
    
3503
    (*ppStatus)->errCode = pTask->errorCode;
29,959,628✔
3504
    (*ppStatus)->status = pTask->status;
29,959,628✔
3505
    (*ppStatus)->lastUpTs = pCtx->currTs;
29,959,628✔
3506
    
3507
    if (STREAM_STATUS_RUNNING != pTask->status) {
29,959,628✔
3508
      msmHandleTaskAbnormalStatus(pCtx, pTask, *ppStatus);
11,488,408✔
3509
    }
3510
    
3511
    if (STREAM_TRIGGER_TASK == pTask->type) {
29,959,628✔
3512
      msmChkHandleTriggerOperations(pCtx, pTask, *ppStatus);
4,143,328✔
3513
    }
3514
  }
3515

3516
_exit:
1,380,910✔
3517

3518
  if (code) {
1,380,910✔
UNCOV
3519
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3520
  }
3521

3522
  return code;
1,380,910✔
3523
}
3524

3525
int32_t msmWatchRecordNewTask(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
×
3526
  int32_t code = TSDB_CODE_SUCCESS;
×
UNCOV
3527
  int32_t lino = 0;
×
3528
  int64_t streamId = pTask->streamId;
×
3529
  SStreamObj* pStream = NULL;
×
3530

3531
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3532
  if (NULL == pStatus) {
×
3533
    SStmStatus status = {0};
×
3534
    TAOS_CHECK_EXIT(mndAcquireStreamById(pCtx->pMnode, streamId, &pStream));
×
3535
    TSDB_CHECK_NULL(pStream, code, lino, _exit, TSDB_CODE_MND_STREAM_NOT_EXIST);
×
UNCOV
3536
    if (STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags) || pStream->pCreate->vtableCalc) {
×
3537
      mndReleaseStream(pCtx->pMnode, pStream);
×
UNCOV
3538
      msttDebug("virtual table task ignored, triggerTblType:%d, vtableCalc:%dstatus:%s", 
×
3539
          pStream->pCreate->triggerTblType, pStream->pCreate->vtableCalc, gStreamStatusStr[pTask->status]);
3540
      return code;
×
3541
    }
3542

3543
    TAOS_CHECK_EXIT(msmInitStmStatus(pCtx, &status, pStream, true));
×
3544
    mndReleaseStream(pCtx->pMnode, pStream);
×
3545

3546
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.streamMap, &streamId, sizeof(streamId), &status, sizeof(status)));
×
UNCOV
3547
    pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
UNCOV
3548
    TSDB_CHECK_NULL(pStatus, code, lino, _exit, terrno);
×
3549
    msttDebug("stream added to streamMap cause of new task status:%s", gStreamStatusStr[pTask->status]);
×
3550
  }
3551

3552
  SStmTaskStatus* pNewTask = NULL;
×
3553
  switch (pTask->type) {
×
3554
    case STREAM_READER_TASK: {
×
3555
      void* pList = STREAM_IS_TRIGGER_READER(pTask->flags) ? (void*)pStatus->trigReaders : (void*)pStatus->calcReaders;
×
UNCOV
3556
      if (NULL == pList) {
×
3557
        mstsError("%sReader list is NULL", STREAM_IS_TRIGGER_READER(pTask->flags) ? "trig" : "calc");
×
3558
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3559
      }
3560
      int32_t readerSize = STREAM_IS_TRIGGER_READER(pTask->flags) ? pStatus->trigReaderNum : pStatus->calcReaderNum;
×
UNCOV
3561
      if ((STREAM_IS_TRIGGER_READER(pTask->flags) && taosArrayGetSize(pList) >= readerSize) ||
×
3562
          MST_LIST_SIZE((SList*)pList) >= readerSize){
×
UNCOV
3563
        mstsError("%sReader list is already full, size:%d, expSize:%d", STREAM_IS_TRIGGER_READER(pTask->flags) ? "trig" : "calc",
×
3564
            (int32_t)taosArrayGetSize(pList), readerSize);
3565
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3566
      }
3567
      
3568
      SStmTaskStatus taskStatus = {0};
×
3569
      taskStatus.pStream = pStatus;
×
3570
      mstSetTaskStatusFromMsg(pCtx, &taskStatus, pTask);
×
UNCOV
3571
      if (STREAM_IS_TRIGGER_READER(pTask->flags)) {
×
3572
        pNewTask = taosArrayPush(pList, &taskStatus);
×
UNCOV
3573
        TSDB_CHECK_NULL(pNewTask, code, lino, _exit, terrno);
×
3574
      } else {
3575
        TAOS_CHECK_EXIT(tdListAppend(pStatus->calcReaders, &taskStatus));
×
3576
      }
3577
      
UNCOV
3578
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pNewTask));
×
3579
      TAOS_CHECK_EXIT(msmSTAddToVgroupMapImpl(streamId, pNewTask, STREAM_IS_TRIGGER_READER(pTask->flags)));
×
3580
      break;
×
3581
    }
3582
    case STREAM_TRIGGER_TASK: {
×
3583
      taosMemoryFreeClear(pStatus->triggerTask);
×
3584
      pStatus->triggerTask = taosMemoryCalloc(1, sizeof(*pStatus->triggerTask));
×
3585
      TSDB_CHECK_NULL(pStatus->triggerTask, code, lino, _exit, terrno);
×
UNCOV
3586
      pStatus->triggerTask->pStream = pStatus;
×
3587
      mstSetTaskStatusFromMsg(pCtx, pStatus->triggerTask, pTask);
×
3588
      pNewTask = pStatus->triggerTask;
×
3589

UNCOV
3590
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pNewTask));
×
3591
      TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pNewTask, 0));
×
3592
      break;
×
3593
    }
3594
    case STREAM_RUNNER_TASK:{
×
UNCOV
3595
      if (NULL == pStatus->runners[pTask->deployId]) {
×
3596
        mstsError("deploy %d runner list is NULL", pTask->deployId);
×
3597
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3598
      }
3599
      if (taosArrayGetSize(pStatus->runners[pTask->deployId]) >= pStatus->runnerNum) {
×
UNCOV
3600
        mstsError("deploy %d runner list is already full, size:%d, expSize:%d", pTask->deployId, 
×
3601
            (int32_t)taosArrayGetSize(pStatus->runners[pTask->deployId]), pStatus->runnerNum);
3602
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3603
      }    
3604
      
3605
      SStmTaskStatus taskStatus = {0};
×
3606
      taskStatus.pStream = pStatus;
×
UNCOV
3607
      mstSetTaskStatusFromMsg(pCtx, &taskStatus, pTask);
×
3608
      pNewTask = taosArrayPush(pStatus->runners[pTask->deployId], &taskStatus);
×
3609
      TSDB_CHECK_NULL(pNewTask, code, lino, _exit, terrno);
×
3610

UNCOV
3611
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pNewTask));
×
3612
      TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pNewTask, pTask->deployId));
×
3613
      break;
×
3614
    }
3615
    default: {
×
UNCOV
3616
      msttError("invalid task type:%d in task status", pTask->type);
×
UNCOV
3617
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
UNCOV
3618
      break;
×
3619
    }
3620
  }
3621

3622
_exit:
×
3623

3624
  if (code) {
×
UNCOV
3625
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3626
  } else {
3627
    msttDebug("new task recored to taskMap/streamMap, task status:%s", gStreamStatusStr[pTask->status]);
×
3628
  }
3629

3630
  return code;
×
3631
}
3632

3633
int32_t msmWatchHandleStatusUpdate(SStmGrpCtx* pCtx) {
×
UNCOV
3634
  int32_t code = TSDB_CODE_SUCCESS;
×
3635
  int32_t lino = 0;
×
UNCOV
3636
  int32_t num = taosArrayGetSize(pCtx->pReq->pStreamStatus);
×
3637

3638
  mstDebug("WATCH: start to handle stream group %d tasks status, taskNum:%d", pCtx->pReq->streamGId, num);
×
3639

UNCOV
3640
  for (int32_t i = 0; i < num; ++i) {
×
3641
    SStmTaskStatusMsg* pTask = taosArrayGet(pCtx->pReq->pStreamStatus, i);
×
3642
    msttDebug("task status %s got, taskIdx:%d", gStreamStatusStr[pTask->status], pTask->taskIdx);
×
3643

UNCOV
3644
    if (pTask->taskId >= mStreamMgmt.lastTaskId) {
×
3645
      mStreamMgmt.lastTaskId = pTask->taskId + 1;
×
3646
    }
3647
    
UNCOV
3648
    SStmTaskStatus** ppStatus = taosHashGet(mStreamMgmt.taskMap, &pTask->streamId, sizeof(pTask->streamId) + sizeof(pTask->taskId));
×
3649
    if (NULL == ppStatus) {
×
UNCOV
3650
      msttInfo("task still not in taskMap, will try to add it, taskIdx:%d", pTask->taskIdx);
×
3651
      
UNCOV
3652
      TAOS_CHECK_EXIT(msmWatchRecordNewTask(pCtx, pTask));
×
3653
      
3654
      continue;
×
3655
    }
3656
    
UNCOV
3657
    (*ppStatus)->status = pTask->status;
×
3658
    (*ppStatus)->lastUpTs = pCtx->currTs;
×
3659
  }
3660

3661
_exit:
×
3662

UNCOV
3663
  if (code) {
×
3664
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3665
  }
3666

UNCOV
3667
  return code;
×
3668
}
3669

3670
void msmRspAddStreamStart(int64_t streamId, SStmGrpCtx* pCtx, int32_t streamNum, SStmAction *pAction) {
276,487✔
3671
  int32_t code = TSDB_CODE_SUCCESS;
276,487✔
3672
  int32_t lino = 0;
276,487✔
3673
  if (NULL == pCtx->pRsp->start.taskList) {
276,487✔
3674
    pCtx->pRsp->start.taskList = taosArrayInit(streamNum, sizeof(SStreamTaskStart));
111,513✔
3675
    TSDB_CHECK_NULL(pCtx->pRsp->start.taskList, code, lino, _exit, terrno);
111,513✔
3676
  }
3677

3678
  SStmTaskId* pId = &pAction->start.triggerId;
276,487✔
3679
  SStreamTaskStart start = {0};
276,487✔
3680
  start.task.type = STREAM_TRIGGER_TASK;
276,487✔
3681
  start.task.streamId = streamId;
276,487✔
3682
  start.task.taskId = pId->taskId;
276,487✔
3683
  start.task.seriousId = pId->seriousId;
276,487✔
3684
  start.task.nodeId = pId->nodeId;
276,487✔
3685
  start.task.taskIdx = pId->taskIdx;
276,487✔
3686

3687
  TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->start.taskList, &start), code, lino, _exit, terrno);
552,974✔
3688
  TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(streamId, pCtx->currTs));
276,487✔
3689

3690
  mstsDebug("stream START added to dnode %d hb rsp, triggerTaskId:%" PRIx64, pId->nodeId, pId->taskId);
276,487✔
3691

3692
  return;
276,487✔
3693

UNCOV
3694
_exit:
×
3695

UNCOV
3696
  mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3697
}
3698

3699

3700
void msmRspAddStreamUndeploy(int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
24,005✔
3701
  int32_t code = TSDB_CODE_SUCCESS;
24,005✔
3702
  int32_t lino = 0;
24,005✔
3703
  int32_t dropNum = taosArrayGetSize(pAction->undeploy.taskList);
24,005✔
3704
  if (NULL == pCtx->pRsp->undeploy.taskList) {
24,005✔
3705
    pCtx->pRsp->undeploy.taskList = taosArrayInit(dropNum, sizeof(SStreamTaskUndeploy));
20,448✔
3706
    TSDB_CHECK_NULL(pCtx->pRsp->undeploy.taskList, code, lino, _exit, terrno);
20,448✔
3707
  }
3708

3709
  SStreamTaskUndeploy undeploy;
24,005✔
3710
  for (int32_t i = 0; i < dropNum; ++i) {
84,554✔
3711
    SStreamTask* pTask = (SStreamTask*)taosArrayGetP(pAction->undeploy.taskList, i);
60,549✔
3712
    undeploy.task = *pTask;
60,549✔
3713
    undeploy.undeployMsg.doCheckpoint = pAction->undeploy.doCheckpoint;
60,549✔
3714
    undeploy.undeployMsg.doCleanup = pAction->undeploy.doCleanup;
60,549✔
3715

3716
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->undeploy.taskList, &undeploy), code, lino, _exit, terrno);
121,098✔
3717
    TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(streamId, pCtx->currTs));
60,549✔
3718

3719
    msttDebug("task UNDEPLOY added to hb rsp, doCheckpoint:%d, doCleanup:%d", undeploy.undeployMsg.doCheckpoint, undeploy.undeployMsg.doCleanup);
60,549✔
3720
  }
3721

3722
  return;
24,005✔
3723

UNCOV
3724
_exit:
×
3725

3726
  mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3727
}
3728

UNCOV
3729
void msmRspAddTriggerUpdate(SMnode * pMnode, int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
×
3730
  int32_t code = TSDB_CODE_SUCCESS;
×
3731
  int32_t lino = 0;
×
3732

3733
  SStmStatus* pStream = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
UNCOV
3734
  if (NULL == pStream) {
×
UNCOV
3735
    mstsDebug("stream already not exists in streamMap, ignore trigger update, streamRemain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
3736
    return;
×
3737
  }
3738

UNCOV
3739
  if (NULL == pStream->triggerTask) {
×
UNCOV
3740
    mstsWarn("no triggerTask exists, ignore trigger update, stopped:%d", atomic_load_8(&pStream->stopped));
×
3741
    return;
×
3742
  }
3743

3744
  SStreamMgmtRsp rsp = {0};
×
3745
  rsp.reqId = INT64_MIN;
×
UNCOV
3746
  rsp.header.msgType = STREAM_MSG_UPDATE_RUNNER;
×
3747
  rsp.task.streamId = streamId;
×
UNCOV
3748
  rsp.task.taskId = pStream->triggerTask->id.taskId;
×
3749

3750
  TAOS_CHECK_EXIT(msmBuildTriggerRunnerTargets(pMnode, pStream, streamId, &rsp.cont.runnerList));  
×
3751

UNCOV
3752
  if (NULL == pCtx->pRsp->rsps.rspList) {
×
UNCOV
3753
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
3754
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
×
3755
  }
3756

UNCOV
3757
  TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), code, lino, _exit, terrno);
×
3758

3759
_exit:
×
3760

3761
  if (code) {
×
UNCOV
3762
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3763
  } else {
UNCOV
3764
    mstsDebug("trigger update rsp added, runnerNum:%d", (int32_t)taosArrayGetSize(rsp.cont.runnerList));
×
3765
  }
3766
}
3767

3768
void msmRspAddUserRecalc(SMnode * pMnode, int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
6,300✔
3769
  int32_t code = TSDB_CODE_SUCCESS;
6,300✔
3770
  int32_t lino = 0;
6,300✔
3771

3772
  SStmStatus* pStream = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
6,300✔
3773
  if (NULL == pStream) {
6,300✔
UNCOV
3774
    mstsDebug("stream already not exists in streamMap, ignore trigger update, streamRemain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
UNCOV
3775
    return;
×
3776
  }
3777

3778
  if (NULL == pStream->triggerTask) {
6,300✔
UNCOV
3779
    mstsWarn("no triggerTask exists, ignore trigger update, stopped:%d", atomic_load_8(&pStream->stopped));
×
UNCOV
3780
    return;
×
3781
  }
3782

3783
  SStreamMgmtRsp rsp = {0};
6,300✔
3784
  rsp.reqId = INT64_MIN;
6,300✔
3785
  rsp.header.msgType = STREAM_MSG_USER_RECALC;
6,300✔
3786
  rsp.task.streamId = streamId;
6,300✔
3787
  rsp.task.taskId = pStream->triggerTask->id.taskId;
6,300✔
3788
  TSWAP(rsp.cont.recalcList, pAction->recalc.recalcList);
6,300✔
3789

3790
  if (NULL == pCtx->pRsp->rsps.rspList) {
6,300✔
3791
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
5,928✔
3792
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
5,928✔
3793
  }
3794

3795
  TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), code, lino, _exit, terrno);
12,600✔
3796

3797
_exit:
6,300✔
3798

3799
  if (code) {
6,300✔
UNCOV
3800
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3801
  } else {
3802
    mstsDebug("user recalc rsp added, recalcNum:%d", (int32_t)taosArrayGetSize(rsp.cont.recalcList));
6,300✔
3803
  }
3804
}
3805

3806

3807
int32_t msmHandleHbPostActions(SStmGrpCtx* pCtx) {
137,528✔
3808
  int32_t code = TSDB_CODE_SUCCESS;
137,528✔
3809
  int32_t lino = 0;
137,528✔
3810
  void* pIter = NULL;
137,528✔
3811
  int32_t streamNum = taosHashGetSize(pCtx->actionStm);
137,528✔
3812

3813
  mstDebug("start to handle stream group %d post actions", pCtx->pReq->streamGId);
137,528✔
3814

3815
  while (1) {
306,792✔
3816
    pIter = taosHashIterate(pCtx->actionStm, pIter);
444,320✔
3817
    if (pIter == NULL) {
444,320✔
3818
      break;
137,528✔
3819
    }
3820

3821
    int64_t* pStreamId = taosHashGetKey(pIter, NULL);
306,792✔
3822
    SStmAction *pAction = (SStmAction *)pIter;
306,792✔
3823
    
3824
    if (STREAM_ACT_UNDEPLOY & pAction->actions) {
306,792✔
3825
      msmRspAddStreamUndeploy(*pStreamId, pCtx, pAction);
24,005✔
3826
      continue;
24,005✔
3827
    }
3828

3829
    if (STREAM_ACT_UPDATE_TRIGGER & pAction->actions) {
282,787✔
UNCOV
3830
      msmRspAddTriggerUpdate(pCtx->pMnode, *pStreamId, pCtx, pAction);
×
3831
    }
3832

3833
    if (STREAM_ACT_RECALC & pAction->actions) {
282,787✔
3834
      msmRspAddUserRecalc(pCtx->pMnode, *pStreamId, pCtx, pAction);
6,300✔
3835
    }
3836

3837
    if (STREAM_ACT_START & pAction->actions) {
282,787✔
3838
      msmRspAddStreamStart(*pStreamId, pCtx, streamNum, pAction);
276,487✔
3839
    }
3840
  }
3841
  
3842
_exit:
137,528✔
3843

3844
  if (pIter) {
137,528✔
UNCOV
3845
    taosHashCancelIterate(pCtx->actionStm, pIter);
×
3846
  }
3847

3848
  if (code) {
137,528✔
UNCOV
3849
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3850
  }
3851

3852
  return code;
137,528✔
3853
}
3854

3855
int32_t msmCheckUpdateDnodeTs(SStmGrpCtx* pCtx) {
15,280,709✔
3856
  int32_t  code = TSDB_CODE_SUCCESS;
15,280,709✔
3857
  int32_t  lino = 0;
15,280,709✔
3858
  int64_t* lastTs = NULL;
15,280,709✔
3859
  bool     noExists = false;
15,280,709✔
3860

3861
  while (true) {
3862
    lastTs = taosHashGet(mStreamMgmt.dnodeMap, &pCtx->pReq->dnodeId, sizeof(pCtx->pReq->dnodeId));
15,823,058✔
3863
    if (NULL == lastTs) {
15,823,058✔
3864
      if (noExists) {
718,262✔
3865
        mstWarn("Got unknown dnode %d hb msg, may be dropped", pCtx->pReq->dnodeId);
175,913✔
3866
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NODE_NOT_EXISTS);
175,913✔
3867
      }
3868

3869
      noExists = true;
542,349✔
3870
      TAOS_CHECK_EXIT(msmSTAddDnodesToMap(pCtx->pMnode));
542,349✔
3871
      
3872
      continue;
542,349✔
3873
    }
3874

UNCOV
3875
    while (true) {
×
3876
      int64_t lastTsValue = atomic_load_64(lastTs);
15,104,796✔
3877
      if (pCtx->currTs > lastTsValue) {
15,104,796✔
3878
        if (lastTsValue == atomic_val_compare_exchange_64(lastTs, lastTsValue, pCtx->currTs)) {
15,103,915✔
3879
          mstDebug("dnode %d lastUpTs updated", pCtx->pReq->dnodeId);
15,103,915✔
3880
          return code;
15,103,915✔
3881
        }
3882

UNCOV
3883
        continue;
×
3884
      }
3885

3886
      return code;
881✔
3887
    }
3888

3889
    break;
3890
  }
3891

3892
_exit:
175,913✔
3893

3894
  if (code) {
175,913✔
3895
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
175,913✔
3896
  }
3897

3898
  return code;  
175,913✔
3899
}
3900

3901
void msmWatchCheckStreamMap(SStmGrpCtx* pCtx) {
×
3902
  SStmStatus* pStatus = NULL;
×
3903
  int32_t trigReaderNum = 0;
×
3904
  int32_t calcReaderNum = 0;
×
UNCOV
3905
  int32_t runnerNum = 0;
×
3906
  int64_t streamId = 0;
×
3907
  void* pIter = NULL;
×
3908
  while (true) {
UNCOV
3909
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
×
UNCOV
3910
    if (NULL == pIter) {
×
3911
      return;
×
3912
    }
3913

3914
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
3915
    pStatus = (SStmStatus*)pIter;
×
3916

3917
    if (NULL == pStatus->triggerTask) {
×
UNCOV
3918
      mstsWarn("no trigger task recored, deployTimes:%" PRId64, pStatus->deployTimes);
×
UNCOV
3919
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
3920
      continue;
×
3921
    }
3922
    
3923
    trigReaderNum = taosArrayGetSize(pStatus->trigReaders);
×
3924
    if (pStatus->trigReaderNum != trigReaderNum) {
×
UNCOV
3925
      mstsWarn("trigReaderNum %d mis-match with expected %d", trigReaderNum, pStatus->trigReaderNum);
×
UNCOV
3926
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
3927
      continue;
×
3928
    }
3929

3930
    calcReaderNum = MST_LIST_SIZE(pStatus->calcReaders);
×
3931
    if (pStatus->calcReaderNum != calcReaderNum) {
×
UNCOV
3932
      mstsWarn("calcReaderNum %d mis-match with expected %d", calcReaderNum, pStatus->calcReaderNum);
×
UNCOV
3933
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
3934
      continue;
×
3935
    }
3936

3937
    for (int32_t i = 0; i < pStatus->runnerDeploys; ++i) {
×
3938
      runnerNum = taosArrayGetSize(pStatus->runners[i]);
×
3939
      if (runnerNum != pStatus->runnerNum) {
×
UNCOV
3940
        mstsWarn("runner deploy %d runnerNum %d mis-match with expected %d", i, runnerNum, pStatus->runnerNum);
×
UNCOV
3941
        msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
UNCOV
3942
        continue;
×
3943
      }
3944
    }
3945
  }
3946
}
3947

3948
int32_t msmWatchHandleEnding(SStmGrpCtx* pCtx, bool watchError) {
278✔
3949
  int32_t code = TSDB_CODE_SUCCESS;
278✔
3950
  int32_t lino = 0;
278✔
3951
  int32_t minVal = watchError ? 0 : 1;
278✔
3952

3953
  if (0 != atomic_val_compare_exchange_8(&mStreamMgmt.watch.ending, 0, 1)) {
278✔
UNCOV
3954
    return code;
×
3955
  }
3956

3957
  while (atomic_load_32(&mStreamMgmt.watch.processing) > minVal) {
278✔
UNCOV
3958
    (void)sched_yield();
×
3959
  }
3960

3961
  if (watchError) {
278✔
3962
    taosHashClear(mStreamMgmt.vgroupMap);
×
3963
    taosHashClear(mStreamMgmt.snodeMap);
×
3964
    taosHashClear(mStreamMgmt.taskMap);
×
UNCOV
3965
    taosHashClear(mStreamMgmt.streamMap);
×
UNCOV
3966
    mstInfo("watch error happends, clear all maps");
×
UNCOV
3967
    goto _exit;
×
3968
  }
3969

3970
  if (0 == atomic_load_8(&mStreamMgmt.watch.taskRemains)) {
278✔
3971
    mstInfo("no stream tasks remain during watch state");
278✔
3972
    goto _exit;
278✔
3973
  }
3974

UNCOV
3975
  msmWatchCheckStreamMap(pCtx);
×
3976

3977
_exit:
278✔
3978

3979
  mStreamMgmt.lastTaskId += 100000;
278✔
3980

3981
  mstInfo("watch state end, new taskId begin from:%" PRIx64, mStreamMgmt.lastTaskId);
278✔
3982

3983
  msmSetInitRuntimeState(MND_STM_STATE_NORMAL);
278✔
3984

3985
  if (code) {
278✔
UNCOV
3986
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3987
  }
3988

3989
  return code;
278✔
3990
}
3991

3992

3993
int32_t msmWatchHandleHbMsg(SStmGrpCtx* pCtx) {
1,112✔
3994
  int32_t code = TSDB_CODE_SUCCESS;
1,112✔
3995
  int32_t lino = 0;
1,112✔
3996
  SStreamHbMsg* pReq = pCtx->pReq;
1,112✔
3997

3998
  (void)atomic_add_fetch_32(&mStreamMgmt.watch.processing, 1);
1,112✔
3999
  
4000
  if (atomic_load_8(&mStreamMgmt.watch.ending)) {
1,112✔
UNCOV
4001
    goto _exit;
×
4002
  }
4003

4004
  TAOS_CHECK_EXIT(msmCheckUpdateDnodeTs(pCtx));
1,112✔
4005
  if (GOT_SNODE(pReq->snodeId)) {
1,112✔
4006
    TAOS_CHECK_EXIT(msmUpdateSnodeUpTs(pCtx));
1,112✔
4007
  }
4008

4009
  if (taosArrayGetSize(pReq->pStreamStatus) > 0) {
1,112✔
UNCOV
4010
    atomic_store_8(&mStreamMgmt.watch.taskRemains, 1);
×
UNCOV
4011
    TAOS_CHECK_EXIT(msmWatchHandleStatusUpdate(pCtx));
×
4012
  }
4013

4014
  if ((pCtx->currTs - MND_STREAM_GET_LAST_TS(STM_EVENT_ACTIVE_BEGIN)) > MST_SHORT_ISOLATION_DURATION) {
1,112✔
4015
    TAOS_CHECK_EXIT(msmWatchHandleEnding(pCtx, false));
278✔
4016
  }
4017

4018
_exit:
1,112✔
4019

4020
  atomic_sub_fetch_32(&mStreamMgmt.watch.processing, 1);
1,112✔
4021
  
4022
  if (code) {
1,112✔
UNCOV
4023
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4024

UNCOV
4025
    (void)msmWatchHandleEnding(pCtx, true);
×
4026
  }
4027

4028
  return code;
1,112✔
4029
}
4030

4031
int32_t msmCheckDeployTrigReader(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStmTaskStatusMsg* pTask, int32_t vgId, int32_t vgNum) {
83,598✔
4032
  int32_t code = TSDB_CODE_SUCCESS;
83,598✔
4033
  int32_t lino = 0;
83,598✔
4034
  bool    readerExists = false;
83,598✔
4035
  int64_t streamId = pTask->streamId;
83,598✔
4036

4037
  int32_t readerNum = taosArrayGetSize(pStatus->trigReaders);
83,598✔
4038
  for (int32_t i = 0; i < readerNum; ++i) {
166,608✔
4039
    SStmTaskStatus* pReader = (SStmTaskStatus*)taosArrayGet(pStatus->trigReaders, i);
100,718✔
4040
    if (pReader->id.nodeId == vgId) {
100,718✔
4041
      readerExists = true;
17,708✔
4042
      break;
17,708✔
4043
    }
4044
  }
4045

4046
  if (!readerExists) {
83,598✔
4047
    if (NULL == pStatus->trigOReaders) {
65,890✔
4048
      pStatus->trigOReaders = taosArrayInit(vgNum, sizeof(SStmTaskStatus));
57,702✔
4049
      TSDB_CHECK_NULL(pStatus->trigOReaders, code, lino, _exit, terrno);
57,702✔
4050
    }
4051
    
4052
    SStmTaskStatus* pState = taosArrayReserve(pStatus->trigOReaders, 1);
65,890✔
4053
    TAOS_CHECK_EXIT(msmTDAddSingleTrigReader(pCtx, pState, vgId, pStatus, streamId));
65,890✔
4054
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pState));
65,890✔
4055
    TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, NULL, pState, true));
65,890✔
4056
  }
4057

4058
_exit:
83,598✔
4059

4060
  if (code) {
83,598✔
UNCOV
4061
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4062
  }
4063

4064
  return code;
83,598✔
4065
}
4066

4067
int32_t msmDeployTriggerOrigReader(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
74,666✔
4068
  int32_t code = TSDB_CODE_SUCCESS, finalCode = TSDB_CODE_SUCCESS;
74,666✔
4069
  int32_t lino = 0;
74,666✔
4070
  int32_t vgId = 0;
74,666✔
4071
  int64_t streamId = pTask->streamId;
74,666✔
4072
  SArray* pTbs = pTask->pMgmtReq->cont.pReqs;
74,666✔
4073
  int32_t tbNum = taosArrayGetSize(pTbs);
74,666✔
4074
  SStreamDbTableName* pName = NULL;
74,666✔
4075
  SSHashObj* pDbVgroups = NULL;
74,666✔
4076
  SStreamMgmtRsp rsp = {0};
74,666✔
4077
  rsp.reqId = pTask->pMgmtReq->reqId;
74,666✔
4078
  rsp.header.msgType = STREAM_MSG_ORIGTBL_READER_INFO;
74,666✔
4079
  int32_t iter = 0;
74,666✔
4080
  void* p = NULL;
74,666✔
4081
  SSHashObj* pVgs = NULL;
74,666✔
4082
  SStreamMgmtReq* pMgmtReq = NULL;
74,666✔
4083
  int8_t stopped = 0;
74,666✔
4084

4085
  if (NULL == pCtx->pRsp->rsps.rspList) {
74,666✔
NEW
4086
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
NEW
4087
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, finalCode, lino, _final, terrno);
×
4088
  }
4089
  
4090
  TSWAP(pTask->pMgmtReq, pMgmtReq);
74,666✔
4091
  rsp.task = *(SStreamTask*)pTask;
74,666✔
4092

4093
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
74,666✔
4094
  if (NULL == pStatus) {
74,666✔
UNCOV
4095
    mstsError("stream not deployed, remainStreams:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
UNCOV
4096
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_RUNNING);
×
4097
  }
4098

4099
  stopped = atomic_load_8(&pStatus->stopped);
74,666✔
4100
  if (stopped) {
74,666✔
UNCOV
4101
    msttInfo("stream stopped %d, ignore deploy trigger reader, vgId:%d", stopped, vgId);
×
UNCOV
4102
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_STOPPED);
×
4103
  }
4104

4105
  if (tbNum <= 0) {
74,666✔
UNCOV
4106
    mstsWarn("empty table list in origReader req, array:%p", pTbs);
×
UNCOV
4107
    goto _exit;
×
4108
  }
4109

4110
  int32_t oReaderNum = taosArrayGetSize(pStatus->trigOReaders);
74,666✔
4111
  if (oReaderNum > 0) {
74,666✔
UNCOV
4112
    mstsWarn("origReaders already exits, num:%d", oReaderNum);
×
UNCOV
4113
    goto _exit;
×
4114
  }
4115

4116
  TAOS_CHECK_EXIT(mstBuildDBVgroupsMap(pCtx->pMnode, &pDbVgroups));
74,666✔
4117
  rsp.cont.vgIds = taosArrayInit(tbNum, sizeof(int32_t));
74,666✔
4118
  TSDB_CHECK_NULL(rsp.cont.vgIds, code, lino, _exit, terrno);
74,666✔
4119

4120
  pVgs = tSimpleHashInit(tbNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
74,666✔
4121
  TSDB_CHECK_NULL(pVgs, code, lino, _exit, terrno);
74,666✔
4122
  
4123
  for (int32_t i = 0; i < tbNum; ++i) {
283,583✔
4124
    pName = (SStreamDbTableName*)taosArrayGet(pTbs, i);
208,917✔
4125
    TAOS_CHECK_EXIT(mstGetTableVgId(pDbVgroups, pName->dbFName, pName->tbName, &vgId));
208,917✔
4126
    TSDB_CHECK_NULL(taosArrayPush(rsp.cont.vgIds, &vgId), code, lino, _exit, terrno);
417,834✔
4127
    TAOS_CHECK_EXIT(tSimpleHashPut(pVgs, &vgId, sizeof(vgId), &vgId, sizeof(vgId)));
208,917✔
4128
  }
4129

4130
  int32_t vgNum = tSimpleHashGetSize(pVgs);
74,666✔
4131
  while (true) {
4132
    p = tSimpleHashIterate(pVgs, p, &iter);
158,264✔
4133
    if (NULL == p) {
158,264✔
4134
      break;
74,666✔
4135
    }
4136
    
4137
    TAOS_CHECK_EXIT(msmCheckDeployTrigReader(pCtx, pStatus, pTask, *(int32_t*)p, vgNum));
83,598✔
4138
  }
4139
  
4140
  vgNum = taosArrayGetSize(pStatus->trigOReaders);
74,666✔
4141
  rsp.cont.readerList = taosArrayInit(vgNum, sizeof(SStreamTaskAddr));
74,666✔
4142
  TSDB_CHECK_NULL(rsp.cont.readerList, code, lino, _exit, terrno);
74,666✔
4143

4144
  SStreamTaskAddr addr;
74,666✔
4145
  for (int32_t i = 0; i < vgNum; ++i) {
140,556✔
4146
    SStmTaskStatus* pOTask = taosArrayGet(pStatus->trigOReaders, i);
65,890✔
4147
    addr.taskId = pOTask->id.taskId;
65,890✔
4148
    addr.nodeId = pOTask->id.nodeId;
65,890✔
4149
    addr.epset = mndGetVgroupEpsetById(pCtx->pMnode, pOTask->id.nodeId);
65,890✔
4150
    TSDB_CHECK_NULL(taosArrayPush(rsp.cont.readerList, &addr), code, lino, _exit, terrno);
131,780✔
4151
    mstsDebug("the %dth otrigReader src added to trigger's virtual orig readerList, TASK:%" PRIx64 " nodeId:%d", i, addr.taskId, addr.nodeId);
65,890✔
4152
  }
4153

4154
_exit:
74,666✔
4155

4156
  tFreeSStreamMgmtReq(pMgmtReq);
74,666✔
4157
  taosMemoryFree(pMgmtReq);
74,666✔
4158

4159
  tSimpleHashCleanup(pVgs);
74,666✔
4160
  mstDestroyDbVgroupsHash(pDbVgroups);
74,666✔
4161

4162
  if (code) {
74,666✔
NEW
4163
    rsp.code = code;
×
4164
    
NEW
4165
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
×
4166

UNCOV
4167
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4168
  } else {
4169
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
149,332✔
4170
  }
4171

4172
_final:
74,666✔
4173

4174
  if (finalCode) {
74,666✔
NEW
4175
    tFreeSStreamMgmtRsp(&rsp);
×
NEW
4176
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code)); 
×
NEW
4177
    msmHandleStreamTaskErr(pCtx, STM_ERR_PROCESSING_ERR, pTask);
×
4178
  }
4179

4180
  return finalCode;
74,666✔
4181
}
4182

4183
int32_t msmGetCalcScanFromList(int64_t streamId, SArray* pList, int64_t uid, SStreamCalcScan** ppRes) {
4,422✔
4184
  int32_t num = taosArrayGetSize(pList);
4,422✔
4185
  SStreamCalcScan* pScan = NULL;
4,422✔
4186
  int32_t code = TSDB_CODE_SUCCESS, lino = 0;
4,422✔
4187
  int64_t planUid = 0;
4,422✔
4188
  for (int32_t i = 0; i < num; ++i) {
4,422✔
4189
    pScan = (SStreamCalcScan*)taosArrayGet(pList, i);
4,422✔
4190
    TAOS_CHECK_EXIT(mstGetScanUidFromPlan(streamId, pScan->scanPlan, &planUid));
4,422✔
4191
    if (0 != planUid && planUid == uid) {
4,422✔
4192
      *ppRes = pScan;
4,422✔
4193
      break;
4,422✔
4194
    }
4195
  }
4196

4197
_exit:
4,422✔
4198

4199
  if (code) {
4,422✔
UNCOV
4200
    mstsError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4201
  }
4202

4203
  return code;
4,422✔
4204
}
4205

4206
int32_t msmCheckDeployCalcReader(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStmTaskStatusMsg* pTask, int32_t vgId, int64_t uid, SStreamTaskAddr* pAddr) {
4,422✔
4207
  int32_t code = TSDB_CODE_SUCCESS;
4,422✔
4208
  int32_t lino = 0;
4,422✔
4209
  bool    readerExists = false;
4,422✔
4210
  int64_t streamId = pTask->streamId;
4,422✔
4211
  SListNode* pNode = listHead(pStatus->calcReaders);
4,422✔
4212
  SStmTaskStatus* pReader = NULL;
4,422✔
4213
  int32_t taskIdx = 0;
4,422✔
4214

4215
  int32_t readerNum = MST_LIST_SIZE(pStatus->calcReaders);
4,422✔
4216
  for (int32_t i = 0; i < readerNum; ++i, pNode = TD_DLIST_NODE_NEXT(pNode)) {
41,004✔
4217
    pReader = (SStmTaskStatus*)pNode->data;
36,582✔
4218
    if (pReader->id.nodeId == vgId && pReader->id.uid == uid) {
36,582✔
UNCOV
4219
      readerExists = true;
×
UNCOV
4220
      pAddr->taskId = pReader->id.taskId;
×
UNCOV
4221
      break;
×
4222
    }
4223
  }
4224

4225
  if (!readerExists) {
4,422✔
4226
    if (NULL == pStatus->calcReaders) {
4,422✔
4227
      pStatus->calcReaders = tdListNew(sizeof(SStmTaskStatus));
×
4228
      TSDB_CHECK_NULL(pStatus->calcReaders, code, lino, _exit, terrno);
×
UNCOV
4229
      taskIdx = 0;
×
4230
    } else {
4231
      pNode = listTail(pStatus->calcReaders);
4,422✔
4232
      pReader = (SStmTaskStatus*)pNode->data;
4,422✔
4233
      taskIdx = pReader->id.taskIdx + 1;
4,422✔
4234
    }
4235

4236
    SStreamCalcScan* pScan = NULL;
4,422✔
4237
    TAOS_CHECK_EXIT(msmGetCalcScanFromList(streamId, pStatus->pCreate->calcScanPlanList, uid, &pScan));
4,422✔
4238
    TSDB_CHECK_NULL(pScan, code, lino, _exit, TSDB_CODE_STREAM_INTERNAL_ERROR);
4,422✔
4239
    pReader = tdListReserve(pStatus->calcReaders);
4,422✔
4240
    TAOS_CHECK_EXIT(msmTDAddSingleCalcReader(pCtx, pReader, taskIdx, vgId, pScan->scanPlan, pStatus, streamId));
4,422✔
4241
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pReader));
4,422✔
4242
    TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, NULL, pReader, false));
4,422✔
4243
    pAddr->taskId = pReader->id.taskId;
4,422✔
4244
  }
4245

4246
  pAddr->epset = mndGetVgroupEpsetById(pCtx->pMnode, vgId);
4,422✔
4247
  pAddr->nodeId = vgId;
4,422✔
4248

4249
_exit:
4,422✔
4250

4251
  if (code) {
4,422✔
UNCOV
4252
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4253
  }
4254

4255
  return code;
4,422✔
4256
}
4257

4258

4259
int32_t msmDeployRunnerOrigReader(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
4,422✔
4260
  int32_t code = TSDB_CODE_SUCCESS, finalCode = TSDB_CODE_SUCCESS;
4,422✔
4261
  int32_t lino = 0;
4,422✔
4262
  int32_t vgId = 0;
4,422✔
4263
  int64_t streamId = pTask->streamId;
4,422✔
4264
  SArray* pReqs = pTask->pMgmtReq->cont.pReqs;
4,422✔
4265
  int32_t reqNum = taosArrayGetSize(pReqs);
4,422✔
4266
  SStreamOReaderDeployReq* pReq = NULL;
4,422✔
4267
  SStreamOReaderDeployRsp* pRsp = NULL;
4,422✔
4268
  SStreamMgmtRsp rsp = {0};
4,422✔
4269
  rsp.reqId = pTask->pMgmtReq->reqId;
4,422✔
4270
  rsp.header.msgType = STREAM_MSG_RUNNER_ORIGTBL_READER;
4,422✔
4271
  SStreamMgmtReq* pMgmtReq = NULL;
4,422✔
4272
  int8_t stopped = 0;
4,422✔
4273
  int32_t vgNum = 0;
4,422✔
4274
  SStreamTaskAddr* pAddr = NULL;
4,422✔
4275

4276
  if (NULL == pCtx->pRsp->rsps.rspList) {
4,422✔
NEW
4277
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
NEW
4278
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, finalCode, lino, _final, terrno);
×
4279
  }
4280
  
4281
  TSWAP(pTask->pMgmtReq, pMgmtReq);
4,422✔
4282
  rsp.task = *(SStreamTask*)pTask;
4,422✔
4283

4284
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
4,422✔
4285
  if (NULL == pStatus) {
4,422✔
UNCOV
4286
    mstsError("stream not deployed, remainStreams:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
UNCOV
4287
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_RUNNING);
×
4288
  }
4289

4290
  stopped = atomic_load_8(&pStatus->stopped);
4,422✔
4291
  if (stopped) {
4,422✔
UNCOV
4292
    msttInfo("stream stopped %d, ignore deploy trigger reader, vgId:%d", stopped, vgId);
×
UNCOV
4293
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_STOPPED);
×
4294
  }
4295

4296
  if (reqNum <= 0) {
4,422✔
UNCOV
4297
    mstsWarn("empty req list in origReader req, array:%p", pReqs);
×
4298
    goto _exit;
×
4299
  }
4300

4301
  rsp.cont.execRspList = taosArrayInit_s(sizeof(SStreamOReaderDeployRsp), reqNum);
4,422✔
4302
  TSDB_CHECK_NULL(rsp.cont.execRspList, code, lino, _exit, terrno);
4,422✔
4303

4304
  for (int32_t i = 0; i < reqNum; ++i) {
8,844✔
4305
    pReq = (SStreamOReaderDeployReq*)taosArrayGet(pReqs, i);
4,422✔
4306
    pRsp = (SStreamOReaderDeployRsp*)taosArrayGet(rsp.cont.execRspList, i);
4,422✔
4307
    pRsp->execId = pReq->execId;
4,422✔
4308
    vgNum = taosArrayGetSize(pReq->vgIds);
4,422✔
4309
    pRsp->vgList = taosArrayInit_s(sizeof(SStreamTaskAddr), vgNum);
4,422✔
4310
    TSDB_CHECK_NULL(pRsp->vgList, code, lino, _exit, terrno);
4,422✔
4311
    
4312
    for (int32_t n = 0; n < vgNum; ++n) {
8,844✔
4313
      vgId = *(int32_t*)taosArrayGet(pReq->vgIds, n);
4,422✔
4314
      pAddr = taosArrayGet(pRsp->vgList, n);
4,422✔
4315
      TAOS_CHECK_EXIT(msmCheckDeployCalcReader(pCtx, pStatus, pTask, vgId, pReq->uid, pAddr));
4,422✔
4316
    }
4317
  }
4318

4319
_exit:
4,422✔
4320

4321
  tFreeSStreamMgmtReq(pMgmtReq);
4,422✔
4322
  taosMemoryFree(pMgmtReq);
4,422✔
4323

4324
  if (code) {
4,422✔
NEW
4325
    rsp.code = code;
×
4326
    
NEW
4327
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
×
UNCOV
4328
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4329
  } else {
4330
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
8,844✔
4331
  }
4332

4333

4334
_final:
4,422✔
4335

4336
  if (finalCode) {
4,422✔
NEW
4337
    tFreeSStreamMgmtRsp(&rsp);
×
NEW
4338
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code)); 
×
NEW
4339
    msmHandleStreamTaskErr(pCtx, STM_ERR_PROCESSING_ERR, pTask);
×
4340
  }
4341

4342
  return finalCode;
4,422✔
4343
}
4344

4345

4346
int32_t msmHandleTaskMgmtReq(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
79,088✔
4347
  int32_t code = TSDB_CODE_SUCCESS;
79,088✔
4348
  int32_t lino = 0;
79,088✔
4349

4350
  switch (pTask->pMgmtReq->type) {
79,088✔
4351
    case STREAM_MGMT_REQ_TRIGGER_ORIGTBL_READER:
74,666✔
4352
      msmDeployTriggerOrigReader(pCtx, pTask);
74,666✔
4353
      break;
74,666✔
4354
    case STREAM_MGMT_REQ_RUNNER_ORIGTBL_READER:
4,422✔
4355
      msmDeployRunnerOrigReader(pCtx, pTask);
4,422✔
4356
      break;
4,422✔
4357
    default:
×
UNCOV
4358
      msttError("Invalid mgmtReq type:%d", pTask->pMgmtReq->type);
×
UNCOV
4359
      code = TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
UNCOV
4360
      break;
×
4361
  }
4362

4363
_exit:
79,088✔
4364

4365
  if (code) {
79,088✔
UNCOV
4366
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4367
  }
4368

4369
  return code;
79,088✔
4370
}
4371

4372
int32_t msmHandleStreamRequests(SStmGrpCtx* pCtx) {
23,712✔
4373
  int32_t code = TSDB_CODE_SUCCESS;
23,712✔
4374
  int32_t lino = 0;
23,712✔
4375
  SStreamHbMsg* pReq = pCtx->pReq;
23,712✔
4376
  SStmTaskStatusMsg* pTask = NULL;
23,712✔
4377
  
4378
  int32_t reqNum = taosArrayGetSize(pReq->pStreamReq);
23,712✔
4379
  if (reqNum > 0 && NULL == pCtx->pRsp->rsps.rspList) {
23,712✔
4380
    pCtx->pRsp->rsps.rspList = taosArrayInit(reqNum, sizeof(SStreamMgmtRsp));
23,712✔
4381
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
23,712✔
4382
  }
4383
  
4384
  for (int32_t i = 0; i < reqNum; ++i) {
102,800✔
4385
    int32_t idx = *(int32_t*)taosArrayGet(pReq->pStreamReq, i);
79,088✔
4386
    pTask = (SStmTaskStatusMsg*)taosArrayGet(pReq->pStreamStatus, idx);
79,088✔
4387
    if (NULL == pTask) {
79,088✔
UNCOV
4388
      mstError("idx %d is NULL, reqNum:%d", idx, reqNum);
×
UNCOV
4389
      continue;
×
4390
    }
4391

4392
    if (NULL == pTask->pMgmtReq) {
79,088✔
UNCOV
4393
      msttError("idx %d without mgmtReq", idx);
×
UNCOV
4394
      continue;
×
4395
    }
4396

4397
    TAOS_CHECK_EXIT(msmHandleTaskMgmtReq(pCtx, pTask));
79,088✔
4398
  }
4399

4400
_exit:
23,712✔
4401

4402
  if (code) {
23,712✔
UNCOV
4403
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4404
  }
4405

4406
  return code;
23,712✔
4407
}
4408

4409
int32_t msmNormalHandleHbMsg(SStmGrpCtx* pCtx) {
15,279,597✔
4410
  int32_t code = TSDB_CODE_SUCCESS;
15,279,597✔
4411
  int32_t lino = 0;
15,279,597✔
4412
  SStreamHbMsg* pReq = pCtx->pReq;
15,279,597✔
4413

4414
  TAOS_CHECK_EXIT(msmCheckUpdateDnodeTs(pCtx));
15,279,597✔
4415
  if (GOT_SNODE(pReq->snodeId)) {
15,103,684✔
4416
    TAOS_CHECK_EXIT(msmUpdateSnodeUpTs(pCtx));
1,459,631✔
4417
  }
4418
  
4419
  if (atomic_load_64(&mStreamMgmt.actionQ->qRemainNum) > 0 && 0 == taosWTryLockLatch(&mStreamMgmt.actionQLock)) {
15,103,287✔
4420
    msmHandleStreamActions(pCtx);
45,716✔
4421
    taosWUnLockLatch(&mStreamMgmt.actionQLock);
45,716✔
4422
  }
4423

4424
  if (taosArrayGetSize(pReq->pStreamReq) > 0 && mstWaitLock(&mStreamMgmt.actionQLock, false)) {
15,103,287✔
4425
    code = msmHandleStreamRequests(pCtx);
23,712✔
4426
    taosWUnLockLatch(&mStreamMgmt.actionQLock);
23,712✔
4427
    TAOS_CHECK_EXIT(code);
23,712✔
4428
  }
4429

4430
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
15,103,287✔
4431
    TAOS_CHECK_EXIT(msmGrpAddDeployVgTasks(pCtx));
64,429✔
4432
  } else {
4433
    TAOS_CHECK_EXIT(msmUpdateVgroupsUpTs(pCtx));
15,038,858✔
4434
  }
4435

4436
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0 && GOT_SNODE(pReq->snodeId)) {
15,103,287✔
4437
    TAOS_CHECK_EXIT(msmGrpAddDeploySnodeTasks(pCtx));
79,253✔
4438
  }
4439

4440
  if (taosHashGetSize(pCtx->deployStm) > 0) {
15,103,287✔
4441
    TAOS_CHECK_EXIT(msmRspAddStreamsDeploy(pCtx));
68,299✔
4442
  }
4443

4444
  if (taosArrayGetSize(pReq->pStreamStatus) > 0) {
15,103,287✔
4445
    TAOS_CHECK_EXIT(msmNormalHandleStatusUpdate(pCtx));
1,380,910✔
4446
  }
4447

4448
  if (taosHashGetSize(pCtx->actionStm) > 0) {
15,103,287✔
4449
    TAOS_CHECK_EXIT(msmHandleHbPostActions(pCtx));
137,528✔
4450
  }
4451

4452
_exit:
15,103,287✔
4453

4454
  if (code) {
15,279,597✔
4455
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
176,310✔
4456
  }
4457

4458
  return code;
15,279,597✔
4459
}
4460

4461
void msmEncodeStreamHbRsp(int32_t code, SRpcHandleInfo *pRpcInfo, SMStreamHbRspMsg* pRsp, SRpcMsg* pMsg) {
15,475,504✔
4462
  int32_t lino = 0;
15,475,504✔
4463
  int32_t tlen = 0;
15,475,504✔
4464
  void   *buf = NULL;
15,475,504✔
4465

4466
  if (TSDB_CODE_SUCCESS != code) {
15,475,504✔
4467
    goto _exit;
176,310✔
4468
  }
4469

4470
  tEncodeSize(tEncodeStreamHbRsp, pRsp, tlen, code);
15,299,194✔
4471
  if (code < 0) {
15,299,194✔
UNCOV
4472
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(code));
×
UNCOV
4473
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
4474
  }
4475

4476
  buf = rpcMallocCont(tlen + sizeof(SStreamMsgGrpHeader));
15,299,194✔
4477
  if (buf == NULL) {
15,299,194✔
UNCOV
4478
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(terrno));
×
UNCOV
4479
    TAOS_CHECK_EXIT(terrno);    
×
4480
  }
4481

4482
  ((SStreamMsgGrpHeader *)buf)->streamGid = pRsp->streamGId;
15,299,194✔
4483
  void *abuf = POINTER_SHIFT(buf, sizeof(SStreamMsgGrpHeader));
15,299,194✔
4484

4485
  SEncoder encoder;
15,280,370✔
4486
  tEncoderInit(&encoder, abuf, tlen);
15,299,194✔
4487
  if ((code = tEncodeStreamHbRsp(&encoder, pRsp)) < 0) {
15,299,194✔
UNCOV
4488
    rpcFreeCont(buf);
×
UNCOV
4489
    buf = NULL;
×
4490
    tEncoderClear(&encoder);
×
4491
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(code));
×
UNCOV
4492
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
4493
  }
4494
  tEncoderClear(&encoder);
15,299,194✔
4495

4496
_exit:
15,475,504✔
4497

4498
  pMsg->code = code;
15,475,504✔
4499
  pMsg->info = *pRpcInfo;
15,475,504✔
4500
  if (TSDB_CODE_SUCCESS == code) {
15,475,504✔
4501
    pMsg->contLen = tlen + sizeof(SStreamMsgGrpHeader);
15,299,194✔
4502
    pMsg->pCont = buf;
15,299,194✔
4503
  }
4504
}
15,475,504✔
4505

4506

4507
int32_t msmHandleStreamHbMsg(SMnode* pMnode, int64_t currTs, SStreamHbMsg* pHb, SRpcMsg *pReq, SRpcMsg* pRspMsg) {
15,475,504✔
4508
  int32_t code = TSDB_CODE_SUCCESS;
15,475,504✔
4509
  SMStreamHbRspMsg rsp = {0};
15,475,504✔
4510
  rsp.streamGId = pHb->streamGId;
15,475,504✔
4511

4512
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, true);
15,475,504✔
4513

4514
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
15,475,504✔
4515
    mstWarn("mnode stream become NOT active, ignore stream hb from dnode %d streamGid %d", pHb->dnodeId, pHb->streamGId);
194,795✔
4516
    goto _exit;
194,795✔
4517
  }
4518

4519
  int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pHb->streamGId);
15,280,709✔
4520
  SStmGrpCtx* pCtx = &mStreamMgmt.tCtx[tidx].grpCtx[pHb->streamGId];
15,280,709✔
4521

4522
  pCtx->tidx = tidx;
15,280,709✔
4523
  pCtx->pMnode = pMnode;
15,280,709✔
4524
  pCtx->currTs = currTs;
15,280,709✔
4525
  pCtx->pReq = pHb;
15,280,709✔
4526
  pCtx->pRsp = &rsp;
15,280,709✔
4527
  pCtx->deployStm = mStreamMgmt.tCtx[pCtx->tidx].deployStm[pHb->streamGId];
15,280,709✔
4528
  pCtx->actionStm = mStreamMgmt.tCtx[pCtx->tidx].actionStm[pHb->streamGId];
15,280,709✔
4529
  
4530
  switch (atomic_load_8(&mStreamMgmt.state)) {
15,280,709✔
4531
    case MND_STM_STATE_WATCH:
1,112✔
4532
      code = msmWatchHandleHbMsg(pCtx);
1,112✔
4533
      break;
1,112✔
4534
    case MND_STM_STATE_NORMAL:
15,279,597✔
4535
      code = msmNormalHandleHbMsg(pCtx);
15,279,597✔
4536
      break;
15,279,597✔
UNCOV
4537
    default:
×
UNCOV
4538
      mstError("Invalid stream state: %d", mStreamMgmt.state);
×
UNCOV
4539
      code = TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
UNCOV
4540
      break;
×
4541
  }
4542

4543
_exit:
15,475,504✔
4544

4545
  msmEncodeStreamHbRsp(code, &pReq->info, &rsp, pRspMsg);
15,475,504✔
4546

4547
  msmCleanStreamGrpCtx(pHb);
15,475,504✔
4548
  msmClearStreamToDeployMaps(pHb);
15,475,504✔
4549

4550
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
15,475,504✔
4551
  
4552
  tFreeSMStreamHbRspMsg(&rsp);
15,475,504✔
4553

4554
  return code;
15,475,504✔
4555
}
4556

4557
void msmHandleBecomeLeader(SMnode *pMnode) {
424,206✔
4558
  if (tsDisableStream) {
424,206✔
UNCOV
4559
    return;
×
4560
  }
4561

4562
  mstInfo("start to process mnode become leader");
424,206✔
4563

4564
  int32_t code = 0;
424,206✔
4565
  streamAddVnodeLeader(MNODE_HANDLE);
424,206✔
4566
  
4567
  taosWLockLatch(&mStreamMgmt.runtimeLock);
424,206✔
4568
  msmDestroyRuntimeInfo(pMnode);
424,206✔
4569
  code = msmInitRuntimeInfo(pMnode);
424,206✔
4570
  taosWUnLockLatch(&mStreamMgmt.runtimeLock);
424,206✔
4571

4572
  if (TSDB_CODE_SUCCESS == code) {
424,206✔
4573
    atomic_store_8(&mStreamMgmt.active, 1);
424,206✔
4574
  }
4575

4576
  mstInfo("mnode stream mgmt active:%d", atomic_load_8(&mStreamMgmt.active));
424,206✔
4577
}
4578

4579
void msmHandleBecomeNotLeader(SMnode *pMnode) {  
624,687✔
4580
  if (tsDisableStream) {
624,687✔
UNCOV
4581
    return;
×
4582
  }
4583

4584
  mstInfo("start to process mnode become not leader");
624,687✔
4585

4586
  streamRemoveVnodeLeader(MNODE_HANDLE);
624,687✔
4587

4588
  if (atomic_val_compare_exchange_8(&mStreamMgmt.active, 1, 0)) {
624,687✔
4589
    taosWLockLatch(&mStreamMgmt.runtimeLock);
424,206✔
4590
    msmDestroyRuntimeInfo(pMnode);
424,206✔
4591
    mStreamMgmt.stat.inactiveTimes++;
424,206✔
4592
    taosWUnLockLatch(&mStreamMgmt.runtimeLock);
424,206✔
4593
  }
4594
}
4595

4596

UNCOV
4597
static void msmRedeployStream(int64_t streamId, SStmStatus* pStatus) {
×
UNCOV
4598
  if (1 == atomic_val_compare_exchange_8(&pStatus->stopped, 1, 0)) {
×
4599
    mstsInfo("try to reset and redeploy stream, deployTimes:%" PRId64, pStatus->deployTimes);
×
UNCOV
4600
    mstPostStreamAction(mStreamMgmt.actionQ, streamId, pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
×
4601
  } else {
UNCOV
4602
    mstsWarn("stream stopped %d already changed", atomic_load_8(&pStatus->stopped));
×
4603
  }
UNCOV
4604
}
×
4605

4606
static bool msmCheckStreamAssign(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
13,963✔
4607
  int32_t code = TSDB_CODE_SUCCESS;
13,963✔
4608
  int32_t lino = 0;
13,963✔
4609
  SStreamObj* pStream = pObj;
13,963✔
4610
  SSnodeObj* pSnode = p1;
13,963✔
4611
  SArray** ppRes = p2;
13,963✔
4612

4613
  if (pStream->mainSnodeId == pSnode->id) {
13,963✔
4614
    if (NULL == *ppRes) {
9,046✔
4615
      int32_t streamNum = sdbGetSize(pMnode->pSdb, SDB_STREAM);
1,946✔
4616
      *ppRes = taosArrayInit(streamNum, POINTER_BYTES);
1,946✔
4617
      TSDB_CHECK_NULL(*ppRes, code, lino, _exit, terrno);
1,946✔
4618
    }
4619

4620
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &pStream), code, lino, _exit, terrno);
18,092✔
4621
  }
4622

4623
  return true;
13,963✔
4624

UNCOV
4625
_exit:
×
4626

UNCOV
4627
  if (code) {
×
UNCOV
4628
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4629
  }  
4630

UNCOV
4631
  *(int32_t*)p3 = code;
×
4632

UNCOV
4633
  return false;
×
4634
}
4635

4636

4637
int32_t msmCheckSnodeReassign(SMnode *pMnode, SSnodeObj* pSnode, SArray** ppRes) {
70,849✔
4638
  int32_t code = TSDB_CODE_SUCCESS;
70,849✔
4639
  int32_t lino = 0;
70,849✔
4640
  
4641
  sdbTraverse(pMnode->pSdb, SDB_STREAM, msmCheckStreamAssign, pSnode, ppRes, &code);
70,849✔
4642
  TAOS_CHECK_EXIT(code);
70,849✔
4643

4644
  int32_t streamNum = taosArrayGetSize(*ppRes);
70,849✔
4645
  if (streamNum > 0 && 0 == pSnode->replicaId) {
70,849✔
4646
    mstError("snode %d has no replica while %d streams assigned", pSnode->id, streamNum);
372✔
4647
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_SNODE_IN_USE);
372✔
4648
  }
4649

4650
  //STREAMTODO CHECK REPLICA UPDATED OR NOT
4651

4652
_exit:
70,849✔
4653

4654
  if (code) {
70,849✔
4655
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
372✔
4656
  }  
4657

4658
  return code;
70,849✔
4659
}
4660

4661
static bool msmCheckLoopStreamSdb(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
606,287✔
4662
  SStreamObj* pStream = pObj;
606,287✔
4663
  int64_t streamId = pStream->pCreate->streamId;
606,287✔
4664
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
606,287✔
4665
  SStmCheckStatusCtx* pCtx = (SStmCheckStatusCtx*)p1;
606,287✔
4666
  int8_t userDropped = atomic_load_8(&pStream->userDropped), userStopped = atomic_load_8(&pStream->userStopped);
606,287✔
4667
  
4668
  if ((userDropped || userStopped) && (NULL == pStatus)) {
606,287✔
4669
    mstsDebug("stream userDropped %d userStopped %d and not in streamMap, ignore it", userDropped, userStopped);
372✔
4670
    return true;
372✔
4671
  }
4672
  
4673
  if (pStatus && !MST_STM_PASS_ISOLATION(pStream, pStatus)) {
605,915✔
4674
    mstsDebug("stream not pass isolation time, updateTime:%" PRId64 ", lastActionTs:%" PRId64 ", currentTs %" PRId64 ", ignore check it", 
429,134✔
4675
        pStream->updateTime, pStatus->lastActionTs, mStreamMgmt.hCtx.currentTs);
4676
    return true;
429,134✔
4677
  }
4678

4679
  if (NULL == pStatus && !MST_STM_STATIC_PASS_SHORT_ISOLATION(pStream)) {
176,781✔
4680
    mstsDebug("stream not pass static isolation time, updateTime:%" PRId64 ", currentTs %" PRId64 ", ignore check it", 
54,109✔
4681
        pStream->updateTime, mStreamMgmt.hCtx.currentTs);
4682
    return true;
54,109✔
4683
  }  
4684

4685
  if (pStatus) {
122,672✔
4686
    if (userDropped || userStopped || MST_IS_USER_STOPPED(atomic_load_8(&pStatus->stopped))) {
121,004✔
4687
      (void)msmRemoveStreamFromMaps(pMnode, streamId);
372✔
4688
    }
4689

4690
    return true;
121,004✔
4691
  }
4692

4693
  mstPostStreamAction(mStreamMgmt.actionQ, streamId, pStream->pCreate->name, NULL, false, STREAM_ACT_DEPLOY);
1,668✔
4694

4695
  return true;
1,668✔
4696
}
4697

4698
void msmCheckLoopStreamMap(SMnode *pMnode) {
55,505✔
4699
  SStmStatus* pStatus = NULL;
55,505✔
4700
  void* pIter = NULL;
55,505✔
4701
  int8_t stopped = 0;
55,505✔
4702
  int64_t streamId = 0;
55,505✔
4703
  
4704
  while (true) {
4705
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
382,159✔
4706
    if (NULL == pIter) {
382,159✔
4707
      break;
55,505✔
4708
    }
4709

4710
    pStatus = (SStmStatus*)pIter;
326,654✔
4711

4712
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
326,654✔
4713
    stopped = atomic_load_8(&pStatus->stopped);
326,654✔
4714
    if (MST_IS_USER_STOPPED(stopped)) {
326,654✔
4715
      mstsDebug("stream already stopped by user, deployTimes:%" PRId64, pStatus->deployTimes);
2,959✔
4716
      (void)msmRemoveStreamFromMaps(pMnode, streamId);
2,959✔
4717
      continue;
2,959✔
4718
    }
4719

4720
    if (!sdbCheckExists(pMnode->pSdb, SDB_STREAM, pStatus->streamName)) {
323,695✔
UNCOV
4721
      mstsDebug("stream already not exists, deployTimes:%" PRId64, pStatus->deployTimes);
×
UNCOV
4722
      (void)msmRemoveStreamFromMaps(pMnode, *(int64_t*)taosHashGetKey(pIter, NULL));
×
UNCOV
4723
      continue;
×
4724
    }
4725

4726
    if (MST_IS_ERROR_STOPPED(stopped)) {
323,695✔
4727
      if (mStreamMgmt.hCtx.currentTs < pStatus->fatalRetryTs) {
7,881✔
4728
        mstsDebug("stream already stopped by error %s, retried times:%" PRId64 ", next time not reached, currTs:%" PRId64 ", nextRetryTs:%" PRId64,
5,254✔
4729
            tstrerror(pStatus->fatalError), pStatus->fatalRetryTimes, mStreamMgmt.hCtx.currentTs, pStatus->fatalRetryTs);
4730
            
4731
        MND_STREAM_SET_LAST_TS(STM_EVENT_STM_TERR, mStreamMgmt.hCtx.currentTs);
5,254✔
4732
        continue;
5,254✔
4733
      }
4734

4735
      mstPostStreamAction(mStreamMgmt.actionQ, *(int64_t*)taosHashGetKey(pIter, NULL), pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
2,627✔
4736
      continue;
2,627✔
4737
    }
4738

4739
    if (MST_IS_GRANT_STOPPED(stopped) && TSDB_CODE_SUCCESS == grantCheckExpire(TSDB_GRANT_STREAMS)) {
315,814✔
4740
      mstPostStreamAction(mStreamMgmt.actionQ, *(int64_t*)taosHashGetKey(pIter, NULL), pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
×
4741
      continue;
×
4742
    }
4743
  }
4744
}
55,505✔
4745

4746
void msmCheckStreamsStatus(SMnode *pMnode) {
400,777✔
4747
  SStmCheckStatusCtx ctx = {0};
400,777✔
4748

4749
  mstDebug("start to check streams status, currTs:%" PRId64, mStreamMgmt.hCtx.currentTs);
400,777✔
4750
  
4751
  if (MST_READY_FOR_SDB_LOOP()) {
400,777✔
4752
    mstDebug("ready to check sdb loop, lastLoopSdbTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_SDB].ts);
82,803✔
4753
    sdbTraverse(pMnode->pSdb, SDB_STREAM, msmCheckLoopStreamSdb, &ctx, NULL, NULL);
82,803✔
4754
    MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_SDB, mStreamMgmt.hCtx.currentTs);
82,803✔
4755
  }
4756

4757
  if (MST_READY_FOR_MAP_LOOP()) {
400,777✔
4758
    mstDebug("ready to check map loop, lastLoopMapTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_MAP].ts);
55,505✔
4759
    msmCheckLoopStreamMap(pMnode);
55,505✔
4760
    MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_MAP, mStreamMgmt.hCtx.currentTs);
55,505✔
4761
  }
4762
}
400,777✔
4763

4764
void msmCheckTaskListStatus(int64_t streamId, SStmTaskStatus** pList, int32_t taskNum) {
3,063,020✔
4765
  for (int32_t i = 0; i < taskNum; ++i) {
6,263,605✔
4766
    SStmTaskStatus* pTask = *(pList + i);
3,202,129✔
4767

4768
    if (atomic_load_8(&((SStmStatus*)pTask->pStream)->stopped)) {
3,202,129✔
4769
      continue;
92,643✔
4770
    }
4771
    
4772
    if (!MST_PASS_ISOLATION(pTask->lastUpTs, 1)) {
3,123,010✔
4773
      continue;
3,119,300✔
4774
    }
4775

4776
    int64_t noUpTs = mStreamMgmt.hCtx.currentTs - pTask->lastUpTs;
3,710✔
4777
    if (STREAM_RUNNER_TASK == pTask->type || STREAM_TRIGGER_TASK == pTask->type) {
3,710✔
4778
      mstsWarn("%s TASK:%" PRIx64 " status not updated for %" PRId64 "ms, will try to redeploy it", 
1,544✔
4779
          gStreamTaskTypeStr[pTask->type], pTask->id.taskId, noUpTs);
4780
          
4781
      msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_TASK_LOST, mStreamMgmt.hCtx.currentTs);
1,544✔
4782
      break;
1,544✔
4783
    }
4784

4785
    mstsInfo("%s TASK:%" PRIx64 " status not updated for %" PRId64 "ms, will try to redeploy it", 
2,166✔
4786
        gStreamTaskTypeStr[pTask->type], pTask->id.taskId, noUpTs);
4787

4788
    int64_t newSid = atomic_add_fetch_64(&pTask->id.seriousId, 1);
2,166✔
4789
    mstsDebug("task %" PRIx64 " SID updated to %" PRIx64, pTask->id.taskId, newSid);
2,166✔
4790

4791
    SStmTaskAction task = {0};
2,166✔
4792
    task.streamId = streamId;
2,166✔
4793
    task.id = pTask->id;
2,166✔
4794
    task.flag = pTask->flags;
2,166✔
4795
    task.type = pTask->type;
2,166✔
4796
    
4797
    mstPostTaskAction(mStreamMgmt.actionQ, &task, STREAM_ACT_DEPLOY);
2,166✔
4798
  }
4799
}
3,063,020✔
4800

4801
void msmCheckVgroupStreamStatus(SHashObj* pStreams) {
168,299✔
4802
  void* pIter = NULL;
168,299✔
4803
  SStmVgStreamStatus* pVg = NULL;
168,299✔
4804
  int64_t streamId = 0;
168,299✔
4805
  
4806
  while (true) {
1,129,211✔
4807
    pIter = taosHashIterate(pStreams, pIter);
1,297,510✔
4808
    if (NULL == pIter) {
1,297,510✔
4809
      break;
168,299✔
4810
    }
4811

4812
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
1,129,211✔
4813
    pVg = (SStmVgStreamStatus*)pIter;
1,129,211✔
4814

4815
    int32_t taskNum = taosArrayGetSize(pVg->trigReaders);
1,129,211✔
4816
    if (taskNum > 0) {
1,129,211✔
4817
      msmCheckTaskListStatus(streamId, taosArrayGet(pVg->trigReaders, 0), taskNum);
683,488✔
4818
    }
4819

4820
    taskNum = taosArrayGetSize(pVg->calcReaders);
1,129,211✔
4821
    if (taskNum > 0) {
1,129,211✔
4822
      msmCheckTaskListStatus(streamId, taosArrayGet(pVg->calcReaders, 0), taskNum);
676,263✔
4823
    }
4824
  }
4825
}
168,299✔
4826

UNCOV
4827
void msmHandleVgroupLost(SMnode *pMnode, int32_t vgId, SStmVgroupStatus* pVg) {
×
UNCOV
4828
  int64_t streamId = 0;
×
UNCOV
4829
  void* pIter = NULL;
×
UNCOV
4830
  SStmVgStreamStatus* pStream = NULL;
×
4831

UNCOV
4832
  if (!MST_PASS_ISOLATION(pVg->lastUpTs, 5)) {
×
UNCOV
4833
    mstDebug("vgroup %d lost and still in watch time, lastUpTs:%" PRId64 ", streamNum:%d", vgId, pVg->lastUpTs, (int32_t)taosHashGetSize(pVg->streamTasks));
×
UNCOV
4834
    return;
×
4835
  }
4836

4837
  
4838
  while (true) {
UNCOV
4839
    pIter = taosHashIterate(pVg->streamTasks, pIter);
×
UNCOV
4840
    if (NULL == pIter) {
×
UNCOV
4841
      break;
×
4842
    }
4843

UNCOV
4844
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
4845
    
4846
    msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_VGROUP_LOST, mStreamMgmt.hCtx.currentTs);
×
4847
  }
4848

UNCOV
4849
  taosHashClear(pVg->streamTasks);
×
4850
}
4851

4852

4853
void msmCheckVgroupStatus(SMnode *pMnode) {
400,777✔
4854
  void* pIter = NULL;
400,777✔
4855
  int32_t code = 0;
400,777✔
4856
  
4857
  while (true) {
1,579,808✔
4858
    pIter = taosHashIterate(mStreamMgmt.vgroupMap, pIter);
1,980,585✔
4859
    if (NULL == pIter) {
1,980,585✔
4860
      break;
400,777✔
4861
    }
4862

4863
    int32_t vgId = *(int32_t*)taosHashGetKey(pIter, NULL);
1,579,808✔
4864
    if ((vgId % MND_STREAM_ISOLATION_PERIOD_NUM) != mStreamMgmt.hCtx.slotIdx) {
1,579,808✔
4865
      continue;
1,408,731✔
4866
    }
4867
    
4868
    SStmVgroupStatus* pVg = (SStmVgroupStatus*)pIter;
171,077✔
4869

4870
    if (MST_PASS_ISOLATION(pVg->lastUpTs, 1)) {
171,077✔
4871
      SVgObj *pVgroup = mndAcquireVgroup(pMnode, vgId);
2,778✔
4872
      if (NULL == pVgroup) {
2,778✔
4873
        mstDebug("vgroup %d no longer exits, will remove all %d tasks in it", vgId, (int32_t)taosHashGetSize(pVg->streamTasks));
2,778✔
4874
        code = taosHashRemove(mStreamMgmt.vgroupMap, &vgId, sizeof(vgId));
2,778✔
4875
        if (code) {
2,778✔
UNCOV
4876
          mstWarn("remove vgroup %d from vgroupMap failed since %s", vgId, tstrerror(code));
×
4877
        }
4878
        continue;
2,778✔
4879
      }
UNCOV
4880
      mndReleaseVgroup(pMnode, pVgroup);
×
4881
      
UNCOV
4882
      mstWarn("vgroup %d lost, lastUpTs:%" PRId64 ", streamNum:%d", vgId, pVg->lastUpTs, (int32_t)taosHashGetSize(pVg->streamTasks));
×
4883
      
UNCOV
4884
      msmHandleVgroupLost(pMnode, vgId, pVg);
×
UNCOV
4885
      continue;
×
4886
    }
4887

4888
    mstDebug("vgroup %d online, try to check tasks status, currTs:%" PRId64 ", lastUpTs:%" PRId64, vgId, mStreamMgmt.hCtx.currentTs, pVg->lastUpTs);
168,299✔
4889

4890
    msmCheckVgroupStreamStatus(pVg->streamTasks);
168,299✔
4891
  }
4892
}
400,777✔
4893

4894
void msmHandleRunnerRedeploy(int64_t streamId, SStmSnodeStreamStatus* pStream, int32_t* deployNum, int32_t* deployId) {
2,130✔
4895
  *deployNum = 0;
2,130✔
4896
  
4897
  for (int32_t i = 0; i < MND_STREAM_RUNNER_DEPLOY_NUM; ++i) {
5,964✔
4898
    if (pStream->runners[i]) {
5,538✔
4899
      int32_t taskNum = taosArrayGetSize(pStream->runners[i]);
2,556✔
4900
      for (int32_t t = 0; t < taskNum; ++t) {
3,408✔
4901
        SStmTaskStatus* pTask = taosArrayGetP(pStream->runners[i], t);
2,556✔
4902
        int8_t stopped = atomic_load_8(&((SStmStatus*)pTask->pStream)->stopped);
2,556✔
4903
        if (stopped) {
2,556✔
4904
          mstsDebug("stream already stopped %d, ignore it", stopped);
1,704✔
4905
          *deployNum = 0;
1,704✔
4906
          return;
1,704✔
4907
        }
4908

4909
        int64_t newSid = atomic_add_fetch_64(&pTask->id.seriousId, 1);
852✔
4910
        mstsDebug("task %" PRIx64 " SID updated to %" PRIx64, pTask->id.taskId, newSid);
852✔
4911
      }
4912
      
4913
      deployId[*deployNum] = i;
852✔
4914
      (*deployNum)++;
852✔
4915
    }
4916
  }
4917
}
4918

4919
void msmHandleSnodeLost(SMnode *pMnode, SStmSnodeStatus* pSnode) {
5,509✔
4920
  pSnode->runnerThreadNum = -1;
5,509✔
4921

4922
  (void)msmSTAddSnodesToMap(pMnode);
5,509✔
4923

4924
  int64_t streamId = 0;
5,509✔
4925
  void* pIter = NULL;
5,509✔
4926
  SStmSnodeStreamStatus* pStream = NULL;
5,509✔
4927
  int32_t deployNum = 0;
5,509✔
4928
  SStmTaskAction task = {0};
5,509✔
4929
  
4930
  while (true) {
4931
    pIter = taosHashIterate(pSnode->streamTasks, pIter);
10,426✔
4932
    if (NULL == pIter) {
10,426✔
4933
      break;
5,509✔
4934
    }
4935

4936
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
4,917✔
4937
    
4938
    task.streamId = streamId;
4,917✔
4939
    
4940
    pStream = (SStmSnodeStreamStatus*)pIter;
4,917✔
4941
    if (pStream->trigger) {
4,917✔
4942
      int8_t stopped = atomic_load_8(&((SStmStatus*)pStream->trigger->pStream)->stopped);
2,787✔
4943
      if (stopped) {
2,787✔
4944
        mstsDebug("stream already stopped %d, ignore it", stopped);
1,704✔
4945
        continue;
1,704✔
4946
      }
4947

4948
      mstsInfo("snode lost with trigger task %" PRIx64 ", will try to restart current stream", pStream->trigger->id.taskId);
1,083✔
4949
      
4950
      msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_SNODE_LOST, mStreamMgmt.hCtx.currentTs);
1,083✔
4951
    } else {
4952
      msmHandleRunnerRedeploy(streamId, pStream, &task.deployNum, task.deployId);
2,130✔
4953
      
4954
      if (task.deployNum > 0) {
2,130✔
4955
        //task.triggerStatus = pStream->trigger;
4956
        task.multiRunner = true;
426✔
4957
        task.type = STREAM_RUNNER_TASK;
426✔
4958
        
4959
        mstPostTaskAction(mStreamMgmt.actionQ, &task, STREAM_ACT_DEPLOY);
426✔
4960
        
4961
        mstsInfo("runner tasks %d redeploys added to actionQ", task.deployNum);
426✔
4962
      }
4963
    }
4964
  }
4965

4966
  taosHashClear(pSnode->streamTasks);
5,509✔
4967
}
5,509✔
4968

4969

4970
void msmCheckSnodeStreamStatus(SHashObj* pStreams) {
55,548✔
4971
  void* pIter = NULL;
55,548✔
4972
  SStmSnodeStreamStatus* pSnode = NULL;
55,548✔
4973
  int64_t streamId = 0;
55,548✔
4974
  
4975
  while (true) {
4976
    pIter = taosHashIterate(pStreams, pIter);
513,273✔
4977
    if (NULL == pIter) {
513,273✔
4978
      break;
55,548✔
4979
    }
4980

4981
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
457,725✔
4982
    pSnode = (SStmSnodeStreamStatus*)pIter;
457,725✔
4983

4984
    if (NULL != pSnode->trigger) {
457,725✔
4985
      msmCheckTaskListStatus(streamId, &pSnode->trigger, 1);
432,606✔
4986
    }
4987

4988
    for (int32_t i = 0; i < MND_STREAM_RUNNER_DEPLOY_NUM; ++i) {
1,830,900✔
4989
      int32_t taskNum = taosArrayGetSize(pSnode->runners[i]);
1,373,175✔
4990
      if (taskNum > 0) {
1,373,175✔
4991
        msmCheckTaskListStatus(streamId, taosArrayGet(pSnode->runners[i], 0), taskNum);
1,270,663✔
4992
      }
4993
    }
4994
  }
4995
}
55,548✔
4996

4997

4998
void msmCheckSnodeStatus(SMnode *pMnode) {
400,777✔
4999
  void* pIter = NULL;
400,777✔
5000
  
5001
  while (true) {
553,159✔
5002
    pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter);
953,936✔
5003
    if (NULL == pIter) {
953,936✔
5004
      break;
400,777✔
5005
    }
5006

5007
    int32_t snodeId = *(int32_t*)taosHashGetKey(pIter, NULL);
553,159✔
5008
    if ((snodeId % MND_STREAM_ISOLATION_PERIOD_NUM) != mStreamMgmt.hCtx.slotIdx) {
553,159✔
5009
      continue;
485,036✔
5010
    }
5011

5012
    mstDebug("start to check snode %d status, currTs:%" PRId64, snodeId, mStreamMgmt.hCtx.currentTs);
68,123✔
5013
    
5014
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
68,123✔
5015
    if (NULL == pSnode->streamTasks) {
68,123✔
5016
      mstDebug("ignore snode %d health check since empty tasks", snodeId);
8,279✔
5017
      continue;
8,279✔
5018
    }
5019
    
5020
    if (MST_PASS_ISOLATION(pSnode->lastUpTs, 1)) {
59,844✔
5021
      mstInfo("snode %d lost, lastUpTs:%" PRId64 ", runnerThreadNum:%d, streamNum:%d", 
4,296✔
5022
          snodeId, pSnode->lastUpTs, pSnode->runnerThreadNum, (int32_t)taosHashGetSize(pSnode->streamTasks));
5023
      
5024
      msmHandleSnodeLost(pMnode, pSnode);
4,296✔
5025
      continue;
4,296✔
5026
    }
5027
    
5028
    mstDebug("snode %d online, try to check tasks status, currTs:%" PRId64 ", lastUpTs:%" PRId64, snodeId, mStreamMgmt.hCtx.currentTs, pSnode->lastUpTs);
55,548✔
5029

5030
    msmCheckSnodeStreamStatus(pSnode->streamTasks);
55,548✔
5031
  }
5032
}
400,777✔
5033

5034

5035
void msmCheckTasksStatus(SMnode *pMnode) {
400,777✔
5036
  mstDebug("start to check tasks status, currTs:%" PRId64, mStreamMgmt.hCtx.currentTs);
400,777✔
5037

5038
  msmCheckVgroupStatus(pMnode);
400,777✔
5039
  msmCheckSnodeStatus(pMnode);
400,777✔
5040
}
400,777✔
5041

5042
void msmCheckSnodesState(SMnode *pMnode) {
400,777✔
5043
  if (!MST_READY_FOR_SNODE_LOOP()) {
400,777✔
5044
    return;
351,413✔
5045
  }
5046

5047
  mstDebug("ready to check snode loop, lastTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_SNODE].ts);
49,364✔
5048

5049
  void* pIter = NULL;
49,364✔
5050
  int32_t snodeId = 0;
49,364✔
5051
  while (true) {
56,873✔
5052
    pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter);
106,237✔
5053
    if (NULL == pIter) {
106,237✔
5054
      break;
49,364✔
5055
    }
5056

5057
    snodeId = *(int32_t*)taosHashGetKey(pIter, NULL);
56,873✔
5058
    if (sdbCheckExists(pMnode->pSdb, SDB_SNODE, &snodeId)) {
56,873✔
5059
      continue;
55,660✔
5060
    }
5061

5062
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
1,213✔
5063
    if (NULL == pSnode->streamTasks) {
1,213✔
UNCOV
5064
      mstDebug("snode %d already cleanup, try to rm it", snodeId);
×
UNCOV
5065
      TAOS_UNUSED(taosHashRemove(mStreamMgmt.snodeMap, &snodeId, sizeof(snodeId)));
×
UNCOV
5066
      continue;
×
5067
    }
5068
    
5069
    mstWarn("snode %d lost while streams remain, will redeploy all and rm it, lastUpTs:%" PRId64 ", runnerThreadNum:%d, streamNum:%d", 
1,213✔
5070
        snodeId, pSnode->lastUpTs, pSnode->runnerThreadNum, (int32_t)taosHashGetSize(pSnode->streamTasks));
5071
    
5072
    msmHandleSnodeLost(pMnode, pSnode);
1,213✔
5073
  }
5074

5075
  MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_MAP, mStreamMgmt.hCtx.currentTs);
49,364✔
5076
}
5077

5078
bool msmCheckNeedHealthCheck(SMnode *pMnode) {
7,912,386✔
5079
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
7,912,386✔
5080
  if (0 == active || MND_STM_STATE_NORMAL != state) {
7,912,386✔
5081
    mstTrace("ignore health check since active:%d state:%d", active, state);
834✔
5082
    return false;
834✔
5083
  }
5084

5085
  if (sdbGetSize(pMnode->pSdb, SDB_STREAM) <= 0) {
7,911,552✔
5086
    mstTrace("ignore health check since no stream now");
7,109,998✔
5087
    return false;
7,109,998✔
5088
  }
5089

5090
  return true;
801,554✔
5091
}
5092

5093
void msmHealthCheck(SMnode *pMnode) {
7,511,609✔
5094
  if (!msmCheckNeedHealthCheck(pMnode)) {
7,511,609✔
5095
    return;
7,110,832✔
5096
  }
5097

5098
  mstDebug("start wait health check, currentTs:%" PRId64,  taosGetTimestampMs());
753,476✔
5099
  
5100
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, false);
400,777✔
5101
  if (!msmCheckNeedHealthCheck(pMnode)) {
400,777✔
UNCOV
5102
    taosWUnLockLatch(&mStreamMgmt.runtimeLock);
×
UNCOV
5103
    return;
×
5104
  }
5105
  
5106
  mStreamMgmt.hCtx.slotIdx = (mStreamMgmt.hCtx.slotIdx + 1) % MND_STREAM_ISOLATION_PERIOD_NUM;
400,777✔
5107
  mStreamMgmt.hCtx.currentTs = taosGetTimestampMs();
400,777✔
5108

5109
  mstDebug("start health check, soltIdx:%d, checkStartTs:%" PRId64, mStreamMgmt.hCtx.slotIdx, mStreamMgmt.hCtx.currentTs);
400,777✔
5110
  
5111
  msmCheckStreamsStatus(pMnode);
400,777✔
5112
  msmCheckTasksStatus(pMnode);
400,777✔
5113
  msmCheckSnodesState(pMnode);
400,777✔
5114

5115
  taosWUnLockLatch(&mStreamMgmt.runtimeLock);
400,777✔
5116

5117
  mstDebug("end health check, soltIdx:%d, checkStartTs:%" PRId64, mStreamMgmt.hCtx.slotIdx, mStreamMgmt.hCtx.currentTs);
400,777✔
5118
}
5119

5120
static bool msmUpdateProfileStreams(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
1,668✔
5121
  SStreamObj *pStream = pObj;
1,668✔
5122
  if (atomic_load_8(&pStream->userDropped) || atomic_load_8(&pStream->userStopped)) {
1,668✔
UNCOV
5123
    return true;
×
5124
  }
5125
  
5126
  pStream->updateTime = *(int64_t*)p1;
1,668✔
5127
  
5128
  (*(int32_t*)p2)++;
1,668✔
5129
  
5130
  return true;
1,668✔
5131
}
5132

UNCOV
5133
int32_t msmGetTriggerTaskAddr(SMnode *pMnode, int64_t streamId, SStreamTaskAddr* pAddr) {
×
UNCOV
5134
  int32_t code = 0;
×
UNCOV
5135
  int8_t  stopped = 0;
×
5136
  
UNCOV
5137
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, true);
×
5138
  
UNCOV
5139
  SStmStatus* pStatus = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
UNCOV
5140
  if (NULL == pStatus) {
×
5141
    mstsError("stream not exists in streamMap, streamRemains:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
UNCOV
5142
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
UNCOV
5143
    goto _exit;
×
5144
  }
5145

UNCOV
5146
  stopped = atomic_load_8(&pStatus->stopped);
×
UNCOV
5147
  if (stopped) {
×
UNCOV
5148
    mstsError("stream already stopped, stopped:%d", stopped);
×
UNCOV
5149
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
UNCOV
5150
    goto _exit;
×
5151
  }
5152

5153
  if (pStatus->triggerTask && STREAM_STATUS_RUNNING == pStatus->triggerTask->status) {
×
UNCOV
5154
    pAddr->taskId = pStatus->triggerTask->id.taskId;
×
5155
    pAddr->nodeId = pStatus->triggerTask->id.nodeId;
×
UNCOV
5156
    pAddr->epset = mndGetDnodeEpsetById(pMnode, pAddr->nodeId);
×
5157
    mstsDebug("stream trigger task %" PRIx64 " got with nodeId %d", pAddr->taskId, pAddr->nodeId);
×
5158
    goto _exit;
×
5159
  }
5160

5161
  mstsError("trigger task %p not running, status:%s", pStatus->triggerTask, pStatus->triggerTask ? gStreamStatusStr[pStatus->triggerTask->status] : "unknown");
×
UNCOV
5162
  code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
5163

5164
_exit:
×
5165
  
5166
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
×
5167

5168
  return code;
×
5169
}
5170

5171
int32_t msmInitRuntimeInfo(SMnode *pMnode) {
424,206✔
5172
  int32_t code = TSDB_CODE_SUCCESS;
424,206✔
5173
  int32_t lino = 0;
424,206✔
5174
  int32_t vnodeNum = sdbGetSize(pMnode->pSdb, SDB_VGROUP);
424,206✔
5175
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
424,206✔
5176
  int32_t dnodeNum = sdbGetSize(pMnode->pSdb, SDB_DNODE);
424,206✔
5177

5178
  MND_STREAM_SET_LAST_TS(STM_EVENT_ACTIVE_BEGIN, taosGetTimestampMs());
847,233✔
5179

5180
  mStreamMgmt.stat.activeTimes++;
424,206✔
5181
  mStreamMgmt.threadNum = tsNumOfMnodeStreamMgmtThreads;
424,206✔
5182
  mStreamMgmt.tCtx = taosMemoryCalloc(mStreamMgmt.threadNum, sizeof(SStmThreadCtx));
424,206✔
5183
  if (NULL == mStreamMgmt.tCtx) {
424,206✔
5184
    code = terrno;
×
UNCOV
5185
    mstError("failed to initialize the stream runtime tCtx, threadNum:%d, error:%s", mStreamMgmt.threadNum, tstrerror(code));
×
5186
    goto _exit;
×
5187
  }
5188

5189
  mStreamMgmt.actionQ = taosMemoryCalloc(1, sizeof(SStmActionQ));
424,206✔
5190
  if (mStreamMgmt.actionQ == NULL) {
424,206✔
UNCOV
5191
    code = terrno;
×
UNCOV
5192
    mError("failed to initialize the stream runtime actionQ, error:%s", tstrerror(code));
×
UNCOV
5193
    goto _exit;
×
5194
  }
5195
  
5196
  mStreamMgmt.actionQ->head = taosMemoryCalloc(1, sizeof(SStmQNode));
424,206✔
5197
  TSDB_CHECK_NULL(mStreamMgmt.actionQ->head, code, lino, _exit, terrno);
424,206✔
5198
  
5199
  mStreamMgmt.actionQ->tail = mStreamMgmt.actionQ->head;
424,206✔
5200
  
5201
  for (int32_t i = 0; i < mStreamMgmt.threadNum; ++i) {
2,544,864✔
5202
    SStmThreadCtx* pCtx = mStreamMgmt.tCtx + i;
2,120,658✔
5203

5204
    for (int32_t m = 0; m < STREAM_MAX_GROUP_NUM; ++m) {
12,723,948✔
5205
      pCtx->deployStm[m] = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
10,603,290✔
5206
      if (pCtx->deployStm[m] == NULL) {
10,603,290✔
UNCOV
5207
        code = terrno;
×
UNCOV
5208
        mError("failed to initialize the stream runtime deployStm[%d][%d], error:%s", i, m, tstrerror(code));
×
5209
        goto _exit;
×
5210
      }
5211
      taosHashSetFreeFp(pCtx->deployStm[m], tDeepFreeSStmStreamDeploy);
10,603,290✔
5212
      
5213
      pCtx->actionStm[m] = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
10,603,290✔
5214
      if (pCtx->actionStm[m] == NULL) {
10,603,290✔
UNCOV
5215
        code = terrno;
×
UNCOV
5216
        mError("failed to initialize the stream runtime actionStm[%d][%d], error:%s", i, m, tstrerror(code));
×
UNCOV
5217
        goto _exit;
×
5218
      }
5219
      taosHashSetFreeFp(pCtx->actionStm[m], mstDestroySStmAction);
10,603,290✔
5220
    }
5221
  }
5222
  
5223
  mStreamMgmt.streamMap = taosHashInit(MND_STREAM_DEFAULT_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
424,206✔
5224
  if (mStreamMgmt.streamMap == NULL) {
424,206✔
5225
    code = terrno;
×
5226
    mError("failed to initialize the stream runtime streamMap, error:%s", tstrerror(code));
×
5227
    goto _exit;
×
5228
  }
5229
  taosHashSetFreeFp(mStreamMgmt.streamMap, mstDestroySStmStatus);
424,206✔
5230
  
5231
  mStreamMgmt.taskMap = taosHashInit(MND_STREAM_DEFAULT_TASK_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
424,206✔
5232
  if (mStreamMgmt.taskMap == NULL) {
424,206✔
5233
    code = terrno;
×
5234
    mError("failed to initialize the stream runtime taskMap, error:%s", tstrerror(code));
×
5235
    goto _exit;
×
5236
  }
5237
  
5238
  mStreamMgmt.vgroupMap = taosHashInit(vnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
424,206✔
5239
  if (mStreamMgmt.vgroupMap == NULL) {
424,206✔
UNCOV
5240
    code = terrno;
×
UNCOV
5241
    mError("failed to initialize the stream runtime vgroupMap, error:%s", tstrerror(code));
×
UNCOV
5242
    goto _exit;
×
5243
  }
5244
  taosHashSetFreeFp(mStreamMgmt.vgroupMap, mstDestroySStmVgroupStatus);
424,206✔
5245

5246
  mStreamMgmt.snodeMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
424,206✔
5247
  if (mStreamMgmt.snodeMap == NULL) {
424,206✔
UNCOV
5248
    code = terrno;
×
UNCOV
5249
    mError("failed to initialize the stream runtime snodeMap, error:%s", tstrerror(code));
×
UNCOV
5250
    goto _exit;
×
5251
  }
5252
  taosHashSetFreeFp(mStreamMgmt.snodeMap, mstDestroySStmSnodeStatus);
424,206✔
5253
  
5254
  mStreamMgmt.dnodeMap = taosHashInit(dnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
424,206✔
5255
  if (mStreamMgmt.dnodeMap == NULL) {
424,206✔
UNCOV
5256
    code = terrno;
×
UNCOV
5257
    mError("failed to initialize the stream runtime dnodeMap, error:%s", tstrerror(code));
×
5258
    goto _exit;
×
5259
  }
5260

5261
  mStreamMgmt.toDeployVgMap = taosHashInit(vnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
424,206✔
5262
  if (mStreamMgmt.toDeployVgMap == NULL) {
424,206✔
UNCOV
5263
    code = terrno;
×
UNCOV
5264
    mError("failed to initialize the stream runtime toDeployVgMap, error:%s", tstrerror(code));
×
UNCOV
5265
    goto _exit;
×
5266
  }
5267
  taosHashSetFreeFp(mStreamMgmt.toDeployVgMap, mstDestroySStmVgTasksToDeploy);
424,206✔
5268
  
5269
  mStreamMgmt.toDeploySnodeMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
424,206✔
5270
  if (mStreamMgmt.toDeploySnodeMap == NULL) {
424,206✔
UNCOV
5271
    code = terrno;
×
UNCOV
5272
    mError("failed to initialize the stream runtime toDeploySnodeMap, error:%s", tstrerror(code));
×
UNCOV
5273
    goto _exit;
×
5274
  }
5275
  taosHashSetFreeFp(mStreamMgmt.toDeploySnodeMap, mstDestroySStmSnodeTasksDeploy);
424,206✔
5276

5277
  mStreamMgmt.toUpdateScanMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
424,206✔
5278
  if (mStreamMgmt.toUpdateScanMap == NULL) {
424,206✔
UNCOV
5279
    code = terrno;
×
UNCOV
5280
    mError("failed to initialize the stream runtime toUpdateScanMap, error:%s", tstrerror(code));
×
5281
    goto _exit;
×
5282
  }
5283
  taosHashSetFreeFp(mStreamMgmt.toUpdateScanMap, mstDestroyScanAddrList);
424,206✔
5284

5285
  TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pMnode));
424,206✔
5286
  TAOS_CHECK_EXIT(msmSTAddDnodesToMap(pMnode));
424,206✔
5287

5288
  mStreamMgmt.lastTaskId = 1;
424,206✔
5289

5290
  int32_t activeStreamNum = 0;
424,206✔
5291
  sdbTraverse(pMnode->pSdb, SDB_STREAM, msmUpdateProfileStreams, &MND_STREAM_GET_LAST_TS(STM_EVENT_ACTIVE_BEGIN), &activeStreamNum, NULL);
424,206✔
5292

5293
  if (activeStreamNum > 0) {
424,206✔
5294
    msmSetInitRuntimeState(MND_STM_STATE_WATCH);
278✔
5295
  } else {
5296
    msmSetInitRuntimeState(MND_STM_STATE_NORMAL);
423,928✔
5297
  }
5298

5299
_exit:
424,206✔
5300

5301
  if (code) {
424,206✔
UNCOV
5302
    msmDestroyRuntimeInfo(pMnode);
×
UNCOV
5303
    mstError("%s failed at line %d since %s", __FUNCTION__, lino, tstrerror(code));
×
5304
  } else {
5305
    mstInfo("mnode stream runtime init done");
424,206✔
5306
  }
5307

5308
  return code;
424,206✔
5309
}
5310

5311

5312

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