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

taosdata / TDengine / #5024

16 Apr 2026 10:31AM UTC coverage: 72.954% (+0.7%) from 72.251%
#5024

push

travis-ci

web-flow
merge: from main to 3.0 branch #35157

120 of 200 new or added lines in 14 files covered. (60.0%)

655 existing lines in 130 files now uncovered.

273150 of 374416 relevant lines covered (72.95%)

129604715.8 hits per line

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

77.31
/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() {
867,214✔
34
  SStmQNode* pQNode = NULL;
867,214✔
35

36
  if (NULL == mStreamMgmt.actionQ) {
867,214✔
37
    return;
433,607✔
38
  }
39

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

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

47
void msmDestroySStmThreadCtx(SStmThreadCtx* pCtx) {
2,165,451✔
48
  for (int32_t m = 0; m < STREAM_MAX_GROUP_NUM; ++m) {
12,992,706✔
49
    taosHashCleanup(pCtx->deployStm[m]);
10,827,255✔
50
    taosHashCleanup(pCtx->actionStm[m]);
10,827,255✔
51
  }
52
}
2,165,451✔
53

54
void msmDestroyThreadCtxs() {
867,214✔
55
  if (NULL == mStreamMgmt.tCtx) {
867,214✔
56
    return;
433,607✔
57
  }
58
  
59
  for (int32_t i = 0; i < mStreamMgmt.threadNum; ++i) {
2,599,058✔
60
    msmDestroySStmThreadCtx(mStreamMgmt.tCtx + i);
2,165,451✔
61
  }
62
  taosMemoryFreeClear(mStreamMgmt.tCtx);
433,607✔
63
}
64

65

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

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

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

91
  memset(mStreamMgmt.lastTs, 0, sizeof(mStreamMgmt.lastTs));
867,214✔
92

93
  mstInfo("mnode stream mgmt destroyed");  
867,214✔
94
}
867,214✔
95

96

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

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

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

111
    pStatus = pStream;
378✔
112
  }
113

114
  int8_t stopped = atomic_load_8(&pStatus->stopped);
7,065✔
115
  if (stopped) {
7,065✔
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) {
7,065✔
121
    pStatus->fatalRetryTimes = 0;
208✔
122
    mstsDebug("reset stream retryTimes, running duation:%" PRId64 "ms", currTs - pStatus->triggerTask->runningStartTs);
208✔
123
  }
124

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

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

136
_exit:
×
137

138
  taosHashRelease(mStreamMgmt.streamMap, pStream);
7,065✔
139

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

145

146
static void msmSetInitRuntimeState(int8_t state) {
433,964✔
147
  switch (state) {
433,964✔
148
    case MND_STM_STATE_WATCH:
700✔
149
      mStreamMgmt.watch.ending = 0;
700✔
150
      mStreamMgmt.watch.taskRemains = 0;
700✔
151
      mStreamMgmt.watch.processing = 0;
700✔
152
      mstInfo("switch to WATCH state");
700✔
153
      break;
700✔
154
    case MND_STM_STATE_NORMAL:
433,264✔
155
      MND_STREAM_SET_LAST_TS(STM_EVENT_NORMAL_BEGIN, taosGetTimestampMs());
865,552✔
156
      mstInfo("switch to NORMAL state");
433,264✔
157
      break;
433,264✔
158
    default:
×
159
      return;
×
160
  }
161
  
162
  atomic_store_8(&mStreamMgmt.state, state);
433,964✔
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) {
462,463✔
175
  int32_t code = TSDB_CODE_SUCCESS;
462,463✔
176
  int32_t lino = 0;
462,463✔
177
  SStmSnodeStatus tasks = {0};
462,463✔
178
  SSnodeObj *pSnode = NULL;
462,463✔
179
  void *pIter = NULL;
462,463✔
180
  while (1) {
181
    pIter = sdbFetch(pMnode->pSdb, SDB_SNODE, pIter, (void **)&pSnode);
506,296✔
182
    if (pIter == NULL) {
506,296✔
183
      break;
462,463✔
184
    }
185

186
    tasks.lastUpTs = taosGetTimestampMs();
43,833✔
187
    code = taosHashPut(mStreamMgmt.snodeMap, &pSnode->id, sizeof(pSnode->id), &tasks, sizeof(tasks));
43,833✔
188
    if (code && TSDB_CODE_DUP_KEY != code) {
43,833✔
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;
43,833✔
196
  
197
    sdbRelease(pMnode->pSdb, pSnode);
43,833✔
198
  }
199

200
  pSnode = NULL;
462,463✔
201

202
_exit:
462,463✔
203

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

208
  return code;
462,463✔
209
}
210

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

223
    code = taosHashPut(mStreamMgmt.dnodeMap, &pDnode->id, sizeof(pDnode->id), &lastUpTs, sizeof(lastUpTs));
1,067,376✔
224
    if (code && TSDB_CODE_DUP_KEY != code) {
1,067,376✔
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,067,376✔
232
    sdbRelease(pMnode->pSdb, pDnode);
1,067,376✔
233
  }
234

235
  pDnode = NULL;
983,440✔
236

237
_exit:
983,440✔
238

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

243
  return code;
983,440✔
244
}
245

246

247

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

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

274
static int32_t msmSTAddToVgStreamHash(SHashObj* pHash, int64_t streamId, SStmTaskStatus* pStatus, bool trigReader) {
693,876✔
275
  int32_t code = TSDB_CODE_SUCCESS;
693,876✔
276
  int32_t lino = 0;
693,876✔
277
  SStmVgStreamStatus* pStream = taosHashGet(pHash, &streamId, sizeof(streamId));
693,876✔
278
  if (NULL == pStream) {
693,876✔
279
    SStmVgStreamStatus stream = {0};
494,033✔
280
    if (trigReader) {
494,033✔
281
      stream.trigReaders = taosArrayInit(1, POINTER_BYTES);
287,215✔
282
      TSDB_CHECK_NULL(stream.trigReaders, code, lino, _exit, terrno);
287,215✔
283
      TSDB_CHECK_NULL(taosArrayPush(stream.trigReaders, &pStatus), code, lino, _exit, terrno);
574,430✔
284
    } else {
285
      stream.calcReaders = taosArrayInit(2, POINTER_BYTES);
206,818✔
286
      TSDB_CHECK_NULL(stream.calcReaders, code, lino, _exit, terrno);
206,818✔
287
      TSDB_CHECK_NULL(taosArrayPush(stream.calcReaders, &pStatus), code, lino, _exit, terrno);
413,636✔
288
    }
289
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &stream, sizeof(stream)));
494,033✔
290
    goto _exit;
494,033✔
291
  }
292
  
293
  if (trigReader) {
199,843✔
294
    if (NULL == pStream->trigReaders) {
23,857✔
295
      pStream->trigReaders = taosArrayInit(1, POINTER_BYTES);
23,857✔
296
      TSDB_CHECK_NULL(pStream->trigReaders, code, lino, _exit, terrno);
23,857✔
297
    }
298
    
299
    TSDB_CHECK_NULL(taosArrayPush(pStream->trigReaders, &pStatus), code, lino, _exit, terrno);
47,714✔
300
    goto _exit;
23,857✔
301
  }
302
  
303
  if (NULL == pStream->calcReaders) {
175,986✔
304
    pStream->calcReaders = taosArrayInit(1, POINTER_BYTES);
115,794✔
305
    TSDB_CHECK_NULL(pStream->calcReaders, code, lino, _exit, terrno);
115,794✔
306
  }
307

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

310
_exit:
175,986✔
311

312
  if (code) {
693,876✔
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", 
693,876✔
317
        trigReader ? "trigReader" : "calcReader", pStatus->id.taskId, pStatus->id.seriousId, pStatus->id.nodeId);
318
  }
319

320
  return code;
693,876✔
321
}
322

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

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

334
    vg.lastUpTs = taosGetTimestampMs();
88,314✔
335
    TAOS_CHECK_EXIT(msmSTAddToVgStreamHash(vg.streamTasks, streamId, pStatus, trigReader));
88,314✔
336
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.vgroupMap, &pStatus->id.nodeId, sizeof(pStatus->id.nodeId), &vg, sizeof(vg)));
88,314✔
337
  } else {
338
    TAOS_CHECK_EXIT(msmSTAddToVgStreamHash(pVg->streamTasks, streamId, pStatus, trigReader));
605,562✔
339
  }
340
  
341
_exit:
693,718✔
342

343
  if (code) {
693,876✔
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);
693,876✔
348
  }
349

350
  return code;
693,876✔
351
}
352

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

361
  while (true) {
×
362
    SStmVgTasksToDeploy* pVg = taosHashAcquire(pVgMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId));
695,218✔
363
    if (NULL == pVg) {
695,218✔
364
      vg.taskList = taosArrayInit(20, sizeof(SStmTaskToDeployExt));
171,405✔
365
      TSDB_CHECK_NULL(vg.taskList, code, lino, _return, terrno);
171,405✔
366
      TSDB_CHECK_NULL(taosArrayPush(vg.taskList, &ext), code, lino, _return, terrno);
342,810✔
367
      code = taosHashPut(pVgMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &vg, sizeof(SStmVgTasksToDeploy));
171,405✔
368
      if (TSDB_CODE_SUCCESS == code) {
171,405✔
369
        goto _return;
171,405✔
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);
523,813✔
381
    if (NULL == pVg->taskList) {
523,813✔
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)) {
1,047,626✔
386
      taosWUnLockLatch(&pVg->lock);
×
387
      TSDB_CHECK_NULL(NULL, code, lino, _return, terrno);
×
388
    }
389
    taosWUnLockLatch(&pVg->lock);
523,813✔
390
    
391
    taosHashRelease(pVgMap, pVg);
523,813✔
392
    break;
523,813✔
393
  }
394
  
395
_return:
695,218✔
396

397
  if (code) {
695,218✔
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);
695,218✔
401
    msttDebug("task added to toDeployVgTaskNum, vgToDeployTaskNum:%d", num);
695,218✔
402
  }
403

404
  return code;
695,218✔
405
}
406

407

408
static int32_t msmSTAddToSnodeStreamHash(SHashObj* pHash, int64_t streamId, SStmTaskStatus* pStatus, int32_t deployId) {
921,057✔
409
  int32_t code = TSDB_CODE_SUCCESS;
921,057✔
410
  int32_t lino = 0;
921,057✔
411
  SStmSnodeStreamStatus* pStream = taosHashGet(pHash, &streamId, sizeof(streamId));
921,057✔
412
  if (NULL == pStream) {
921,057✔
413
    SStmSnodeStreamStatus stream = {0};
212,447✔
414
    if (deployId < 0) {
212,447✔
415
      stream.trigger = pStatus;
3,352✔
416
    } else {
417
      stream.runners[deployId] = taosArrayInit(2, POINTER_BYTES);
209,095✔
418
      TSDB_CHECK_NULL(stream.runners[deployId], code, lino, _exit, terrno);
209,095✔
419
      TSDB_CHECK_NULL(taosArrayPush(stream.runners[deployId], &pStatus), code, lino, _exit, terrno);
418,190✔
420
    }
421
    
422
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &stream, sizeof(stream)));
212,447✔
423
    goto _exit;
212,447✔
424
  }
425
  
426
  if (deployId < 0) {
708,610✔
427
    if (NULL != pStream->trigger) {
202,322✔
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;
202,322✔
433
    goto _exit;
202,322✔
434
  }
435
  
436
  if (NULL == pStream->runners[deployId]) {
506,288✔
437
    pStream->runners[deployId] = taosArrayInit(2, POINTER_BYTES);
399,749✔
438
    TSDB_CHECK_NULL(pStream->runners[deployId], code, lino, _exit, terrno);
399,749✔
439
  }
440

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

443
_exit:
506,288✔
444

445
  if (code) {
921,057✔
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", 
921,057✔
450
        (deployId < 0) ? "trigger" : "runner", pStatus->id.taskId, pStatus->id.seriousId, pStatus->id.nodeId, deployId);
451
  }
452

453
  return code;
921,057✔
454
}
455

456

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

461
  SStmSnodeStatus* pSnode = taosHashGet(mStreamMgmt.snodeMap, &pStatus->id.nodeId, sizeof(pStatus->id.nodeId));
921,057✔
462
  if (NULL == pSnode) {
921,057✔
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) {
921,057✔
467
      pSnode->streamTasks = taosHashInit(2, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
26,607✔
468
      TSDB_CHECK_NULL(pSnode->streamTasks, code, lino, _exit, terrno);
26,607✔
469
      taosHashSetFreeFp(pSnode->streamTasks, mstDestroySStmSnodeStreamStatus);
26,607✔
470
    }
471
    
472
    TAOS_CHECK_EXIT(msmSTAddToSnodeStreamHash(pSnode->streamTasks, streamId, pStatus, deployId));
921,057✔
473
  }
474
  
475
_exit:
921,057✔
476

477
  if (code) {
921,057✔
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", 
921,057✔
481
        pStatus->id.taskId, pStatus->id.taskIdx, pStatus->id.nodeId);
482
  }
483

484
  return code;
921,057✔
485
}
486

487

488

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

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

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

507
      code = taosHashPut(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &snode, sizeof(snode));
236✔
508
      if (TSDB_CODE_SUCCESS == code) {
236✔
509
        goto _return;
236✔
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);
205,438✔
521
    if (NULL == pSnode->triggerList) {
205,438✔
522
      pSnode->triggerList = taosArrayInit(10, sizeof(SStmTaskToDeployExt));
54,155✔
523
      if (NULL == pSnode->triggerList) {
54,155✔
524
        taosWUnLockLatch(&pSnode->lock);
×
525
        TSDB_CHECK_NULL(pSnode->triggerList, code, lino, _return, terrno);
×
526
      }
527
    }
528
    
529
    ext.deploy = *pDeploy;
205,438✔
530
    ext.deployed = false;
205,438✔
531
    
532
    if (NULL == taosArrayPush(pSnode->triggerList, &ext)) {
410,876✔
533
      taosWUnLockLatch(&pSnode->lock);
×
534
      TSDB_CHECK_NULL(NULL, code, lino, _return, terrno);
×
535
    }
536
    taosWUnLockLatch(&pSnode->lock);
205,438✔
537
    
538
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
205,438✔
539
    break;
205,438✔
540
  }
541
  
542
_return:
205,674✔
543

544
  if (code) {
205,674✔
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);
205,674✔
548
  }
549

550
  return code;
205,674✔
551
}
552

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

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

567
      ext.deploy = *pDeploy;
57,413✔
568
      ext.deployed = false;
57,413✔
569
      TSDB_CHECK_NULL(taosArrayPush(snode.runnerList, &ext), code, lino, _return, terrno);
114,826✔
570

571
      code = taosHashPut(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &snode, sizeof(snode));
57,413✔
572
      if (TSDB_CODE_SUCCESS == code) {
57,413✔
573
        goto _return;
57,413✔
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);
657,970✔
585
    if (NULL == pSnode->runnerList) {
657,970✔
586
      pSnode->runnerList = taosArrayInit(10, sizeof(SStmTaskToDeployExt));
236✔
587
      if (NULL == pSnode->runnerList) {
236✔
588
        taosWUnLockLatch(&pSnode->lock);
×
589
        TSDB_CHECK_NULL(pSnode->runnerList, code, lino, _return, terrno);
×
590
      }
591
    }
592
    
593
    ext.deploy = *pDeploy;
657,970✔
594
    ext.deployed = false;
657,970✔
595
    
596
    if (NULL == taosArrayPush(pSnode->runnerList, &ext)) {
1,315,940✔
597
      taosWUnLockLatch(&pSnode->lock);
×
598
      TSDB_CHECK_NULL(NULL, code, lino, _return, terrno);
×
599
    }
600
    taosWUnLockLatch(&pSnode->lock);
657,970✔
601
    
602
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
657,970✔
603
    break;
657,970✔
604
  }
605
  
606
_return:
715,383✔
607

608
  if (code) {
715,383✔
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);
715,383✔
612
  }
613

614
  return code;
715,383✔
615
}
616

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

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

632
_exit:
651,216✔
633

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

638
  return code;
651,216✔
639
}
640

641

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

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

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

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

672
        continue;
×
673
      }
674

675
      return code;
16,953✔
676
    }
677

678
    break;
679
  }
680

681
_exit:
236✔
682

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

687
  return code;  
236✔
688
}
689

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

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

707
      continue;
×
708
    }
709

710
    return;
99,935✔
711
  }  
712
}
713

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

719
  mstDebug("start to update vgroups upTs");
17,430,393✔
720
  
721
  for (int32_t i = 0; i < vgNum; ++i) {
73,497,518✔
722
    int32_t* vgId = taosArrayGet(pCtx->pReq->pVgLeaders, i);
56,067,125✔
723

724
    msmUpdateVgroupUpTs(pCtx, *vgId);
56,067,125✔
725
  }
726

727
_exit:
17,430,393✔
728

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

733
  return code;
17,430,393✔
734
}
735

736

737

738
void* msmSearchCalcCacheScanPlan(SArray* pList) {
376,984✔
739
  int32_t num = taosArrayGetSize(pList);
376,984✔
740
  for (int32_t i = 0; i < num; ++i) {
1,173,774✔
741
    SStreamCalcScan* pScan = taosArrayGet(pList, i);
975,849✔
742
    if (pScan->readFromCache) {
975,849✔
743
      return pScan->scanPlan;
179,059✔
744
    }
745
  }
746

747
  return NULL;
197,925✔
748
}
749

750
int32_t msmBuildReaderDeployInfo(SStmTaskDeploy* pDeploy, void* calcScanPlan, SStmStatus* pInfo, bool triggerReader) {
695,218✔
751
  SStreamReaderDeployMsg* pMsg = &pDeploy->msg.reader;
695,218✔
752
  pMsg->triggerReader = triggerReader;
695,218✔
753
  
754
  if (triggerReader) {
695,218✔
755
    SStreamReaderDeployFromTrigger* pTrigger = &pMsg->msg.trigger;
311,847✔
756
    pTrigger->triggerTblName = pInfo->pCreate->triggerTblName;
311,847✔
757
    pTrigger->triggerTblUid = pInfo->pCreate->triggerTblUid;
311,847✔
758
    pTrigger->triggerTblSuid = pInfo->pCreate->triggerTblSuid;
311,847✔
759
    pTrigger->triggerTblType = pInfo->pCreate->triggerTblType;
311,847✔
760
    pTrigger->isTriggerTblVirt = STREAM_IS_VIRTUAL_TABLE(pInfo->pCreate->triggerTblType, pInfo->pCreate->flags);
311,847✔
761
    pTrigger->deleteReCalc = pInfo->pCreate->deleteReCalc;
311,847✔
762
    pTrigger->deleteOutTbl = pInfo->pCreate->deleteOutTbl;
311,847✔
763
    pTrigger->partitionCols = pInfo->pCreate->partitionCols;
311,847✔
764
    pTrigger->triggerCols = pInfo->pCreate->triggerCols;
311,847✔
765
    //pTrigger->triggerPrevFilter = pStream->pCreate->triggerPrevFilter;
766
    pTrigger->triggerScanPlan = pInfo->pCreate->triggerScanPlan;
311,847✔
767
    pTrigger->calcCacheScanPlan = msmSearchCalcCacheScanPlan(pInfo->pCreate->calcScanPlanList);
311,847✔
768
  } else {
769
    SStreamReaderDeployFromCalc* pCalc = &pMsg->msg.calc;
383,371✔
770
    pCalc->execReplica = pInfo->runnerDeploys * pInfo->runnerReplica;
383,371✔
771
    if (calcScanPlan) {
383,371✔
772
      pCalc->calcScanPlan = taosStrdup(calcScanPlan);
383,371✔
773
      if (NULL == pCalc->calcScanPlan) {
383,371✔
NEW
774
        return terrno;
×
775
      }
776
      pCalc->freeScanPlan = true;
383,371✔
777
    }
778
  }
779

780
  return TSDB_CODE_SUCCESS;
695,218✔
781
}
782

783
int32_t msmBuildTriggerRunnerTargets(SMnode* pMnode, SStmStatus* pInfo, int64_t streamId, SArray** ppRes) {
202,322✔
784
  int32_t code = TSDB_CODE_SUCCESS;
202,322✔
785
  int32_t lino = 0;
202,322✔
786

787
  if (pInfo->runnerDeploys > 0) {
202,322✔
788
    *ppRes = taosArrayInit(pInfo->runnerDeploys, sizeof(SStreamRunnerTarget));
202,322✔
789
    TSDB_CHECK_NULL(*ppRes, code, lino, _exit, terrno);
202,322✔
790
  }
791
  
792
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
809,288✔
793
    SStmTaskStatus* pStatus = taosArrayGetLast(pInfo->runners[i]);
606,966✔
794
    TSDB_CHECK_NULL(pStatus, code, lino, _exit, terrno);
606,966✔
795

796
    if (!STREAM_IS_TOP_RUNNER(pStatus->flags)) {
606,966✔
797
      mstsError("the last runner task %" PRIx64 " SID:%" PRId64 " tidx:%d in deploy %d is not top runner", 
×
798
          pStatus->id.taskId, pStatus->id.seriousId, pStatus->id.taskIdx, i);
799
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
800
    }
801
    
802
    SStreamRunnerTarget runner;
605,649✔
803
    runner.addr.taskId = pStatus->id.taskId;
606,966✔
804
    runner.addr.nodeId = pStatus->id.nodeId;
606,966✔
805
    runner.addr.epset = mndGetDnodeEpsetById(pMnode, pStatus->id.nodeId);
606,966✔
806
    runner.execReplica = pInfo->runnerReplica; 
606,966✔
807
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &runner), code, lino, _exit, terrno);
1,213,932✔
808
    mstsDebug("the %dth runner target added to trigger's runnerList, TASK:%" PRIx64 , i, runner.addr.taskId);
606,966✔
809
  }
810

811
_exit:
202,322✔
812

813
  if (code) {
202,322✔
814
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
815
  }
816
  
817
  return TSDB_CODE_SUCCESS;
202,322✔
818
}
819

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

832
  mndReleaseSnode(pMnode, pSnode);
×
833

834
  pInfo->leaderEpSet = mndGetDnodeEpsetById(pMnode, pInfo->leaderSnodeId);
×
835
  if (GOT_SNODE(pInfo->replicaSnodeId)) {
×
836
    pInfo->replicaEpSet = mndGetDnodeEpsetById(pMnode, pInfo->replicaSnodeId);
×
837
  }
838

839
  return TSDB_CODE_SUCCESS;
×
840
}
841

842
int32_t msmBuildTriggerDeployInfo(SMnode* pMnode, SStmStatus* pInfo, SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
205,674✔
843
  int32_t code = TSDB_CODE_SUCCESS;
205,674✔
844
  int32_t lino = 0;
205,674✔
845
  int64_t streamId = pStream->pCreate->streamId;
205,674✔
846
  SStreamTriggerDeployMsg* pMsg = &pDeploy->msg.trigger;
205,674✔
847
  
848
  pMsg->triggerType = pStream->pCreate->triggerType;
205,674✔
849
  pMsg->igDisorder = pStream->pCreate->igDisorder;
205,674✔
850
  pMsg->fillHistory = pStream->pCreate->fillHistory;
205,674✔
851
  pMsg->fillHistoryFirst = pStream->pCreate->fillHistoryFirst;
205,674✔
852
  pMsg->lowLatencyCalc = pStream->pCreate->lowLatencyCalc;
205,674✔
853
  pMsg->igNoDataTrigger = pStream->pCreate->igNoDataTrigger;
205,674✔
854
  pMsg->enableMultiGroupCalc = pStream->pCreate->enableMultiGroupCalc;
205,674✔
855
  pMsg->isTriggerTblVirt = STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags);
205,674✔
856
  pMsg->triggerHasPF = pStream->pCreate->triggerHasPF;
205,674✔
857
  pMsg->isTriggerTblStb = (pStream->pCreate->triggerTblType == TSDB_SUPER_TABLE);
205,674✔
858
  pMsg->precision = pStream->pCreate->triggerPrec;
205,674✔
859
  pMsg->partitionCols = pInfo->pCreate->partitionCols;
205,674✔
860

861
  pMsg->pNotifyAddrUrls = pInfo->pCreate->pNotifyAddrUrls;
205,674✔
862
  pMsg->notifyEventTypes = pStream->pCreate->notifyEventTypes;
205,674✔
863
  pMsg->addOptions = pStream->pCreate->addOptions;
205,674✔
864
  pMsg->notifyHistory = pStream->pCreate->notifyHistory;
205,674✔
865

866
  pMsg->maxDelay = pStream->pCreate->maxDelay;
205,674✔
867
  pMsg->fillHistoryStartTime = pStream->pCreate->fillHistoryStartTime;
205,674✔
868
  pMsg->watermark = pStream->pCreate->watermark;
205,674✔
869
  pMsg->expiredTime = pStream->pCreate->expiredTime;
205,674✔
870
  pMsg->idleTimeoutMs = pStream->pCreate->idleTimeoutMs;
205,674✔
871
  pMsg->trigger = pInfo->pCreate->trigger;
205,674✔
872

873
  pMsg->eventTypes = pStream->pCreate->eventTypes;
205,674✔
874
  pMsg->placeHolderBitmap = pStream->pCreate->placeHolderBitmap;
205,674✔
875
  pMsg->calcTsSlotId = pStream->pCreate->calcTsSlotId;
205,674✔
876
  pMsg->triTsSlotId = pStream->pCreate->triTsSlotId;
205,674✔
877
  pMsg->calcPkSlotId = pStream->pCreate->calcPkSlotId;
205,674✔
878
  pMsg->triPkSlotId = pStream->pCreate->triPkSlotId;
205,674✔
879
  pMsg->triggerPrevFilter = pInfo->pCreate->triggerPrevFilter;
205,674✔
880
  if (STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags)) {
205,674✔
881
    pMsg->triggerScanPlan = pInfo->pCreate->triggerScanPlan;
65,137✔
882
    pMsg->calcCacheScanPlan = msmSearchCalcCacheScanPlan(pInfo->pCreate->calcScanPlanList);
65,137✔
883
  }
884

885
  SStreamTaskAddr addr;
205,235✔
886
  int32_t triggerReaderNum = taosArrayGetSize(pInfo->trigReaders);
205,674✔
887
  if (triggerReaderNum > 0) {
205,674✔
888
    pMsg->readerList = taosArrayInit(triggerReaderNum, sizeof(SStreamTaskAddr));
201,394✔
889
    TSDB_CHECK_NULL(pMsg->readerList, code, lino, _exit, terrno);
201,394✔
890
  }
891
  
892
  for (int32_t i = 0; i < triggerReaderNum; ++i) {
454,238✔
893
    SStmTaskStatus* pStatus = taosArrayGet(pInfo->trigReaders, i);
248,564✔
894
    addr.taskId = pStatus->id.taskId;
248,564✔
895
    addr.nodeId = pStatus->id.nodeId;
248,564✔
896
    addr.epset = mndGetVgroupEpsetById(pMnode, pStatus->id.nodeId);
248,564✔
897
    TSDB_CHECK_NULL(taosArrayPush(pMsg->readerList, &addr), code, lino, _exit, terrno);
497,128✔
898
    mstsDebug("the %dth trigReader src added to trigger's readerList, TASK:%" PRIx64 " nodeId:%d", i, addr.taskId, addr.nodeId);
248,564✔
899
  }
900

901
  pMsg->leaderSnodeId = pStream->mainSnodeId;
205,674✔
902
  pMsg->streamName = pInfo->streamName;
205,674✔
903
  pMsg->nodelayCreateSubtable = pStream->pCreate->nodelayCreateSubtable;
205,674✔
904

905
  if (0 == pInfo->runnerNum) {
205,674✔
906
    mstsDebug("no runner task, skip set trigger's runner list, deployNum:%d", pInfo->runnerDeploys);
3,352✔
907
    return code;
3,352✔
908
  }
909

910
  TAOS_CHECK_EXIT(msmBuildTriggerRunnerTargets(pMnode, pInfo, streamId, &pMsg->runnerList));
202,322✔
911

912
_exit:
202,322✔
913

914
  if (code) {
202,322✔
915
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
916
  } else {
917
    mstsDebug("trigger deploy info built, readerNum:%d, runnerNum:%d", (int32_t)taosArrayGetSize(pMsg->readerList), (int32_t)taosArrayGetSize(pMsg->runnerList));
202,322✔
918
  }
919
  
920
  return TSDB_CODE_SUCCESS;
202,322✔
921
}
922

923

924
int32_t msmBuildRunnerDeployInfo(SStmTaskDeploy* pDeploy, SSubplan *plan, SStreamObj* pStream, SStmStatus* pInfo, bool topPlan) {
715,383✔
925
  int32_t code = TSDB_CODE_SUCCESS;
715,383✔
926
  int32_t lino = 0;
715,383✔
927
  int64_t streamId = pStream->pCreate->streamId;
715,383✔
928
  SStreamRunnerDeployMsg* pMsg = &pDeploy->msg.runner;
715,383✔
929
  //TAOS_CHECK_EXIT(qSubPlanToString(plan, &pMsg->pPlan, NULL));
930

931
  pMsg->execReplica = pInfo->runnerReplica;
715,383✔
932
  pMsg->streamName = pInfo->streamName;
715,383✔
933
  //TAOS_CHECK_EXIT(nodesCloneNode((SNode*)plan, (SNode**)&pMsg->pPlan));
934
  pMsg->pPlan = plan;
715,383✔
935
  pMsg->outDBFName = pInfo->pCreate->outDB;
715,383✔
936
  pMsg->outTblName = pInfo->pCreate->outTblName;
715,383✔
937
  pMsg->outTblType = pStream->pCreate->outTblType;
715,383✔
938
  pMsg->lowLatencyCalc = pStream->pCreate->lowLatencyCalc;
715,383✔
939
  pMsg->calcNotifyOnly = pStream->pCreate->calcNotifyOnly;
715,383✔
940
  pMsg->topPlan = topPlan;
715,383✔
941
  pMsg->pNotifyAddrUrls = pInfo->pCreate->pNotifyAddrUrls;
715,383✔
942
  pMsg->addOptions = pStream->pCreate->addOptions;
715,383✔
943
  if ((WINDOW_TYPE_INTERVAL == pStream->pCreate->triggerType && pStream->pCreate->trigger.sliding.overlap) ||
715,383✔
944
      (WINDOW_TYPE_COUNT == pStream->pCreate->triggerType &&
702,396✔
945
       pStream->pCreate->trigger.count.sliding < pStream->pCreate->trigger.count.countVal)) {
99,372✔
946
    pMsg->addOptions |= CALC_SLIDING_OVERLAP;
72,732✔
947
  }
948
  pMsg->outCols = pInfo->pCreate->outCols;
715,383✔
949
  pMsg->outTags = pInfo->pCreate->outTags;
715,383✔
950
  pMsg->outStbUid = pStream->pCreate->outStbUid;
715,383✔
951
  pMsg->outStbSversion = pStream->pCreate->outStbSversion;
715,383✔
952
  
953
  pMsg->subTblNameExpr = pInfo->pCreate->subTblNameExpr;
715,383✔
954
  pMsg->tagValueExpr = pInfo->pCreate->tagValueExpr;
715,383✔
955
  pMsg->forceOutCols = pInfo->pCreate->forceOutCols;
715,383✔
956

957
  pMsg->colCids = pInfo->pCreate->colCids;
715,383✔
958
  pMsg->tagCids = pInfo->pCreate->tagCids;
715,383✔
959
_exit:
715,383✔
960

961
  if (code) {
715,383✔
962
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
963
  }
964
  
965
  return code;
715,383✔
966
}
967

968

969
static int32_t msmSTAddToVgroupMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SList* pList, SStmTaskStatus* pTask, bool trigReader) {
476,320✔
970
  int32_t code = TSDB_CODE_SUCCESS;
476,320✔
971
  int32_t lino = 0;
476,320✔
972
  int32_t taskNum = pTask ? 1 : (pList ? MST_LIST_SIZE(pList) :taosArrayGetSize(pTasks));
476,320✔
973
  SListNode* pNode = pList ? listHead(pList) : NULL;
476,320✔
974
  
975
  for (int32_t i = 0; i < taskNum; ++i) {
1,170,196✔
976
    SStmTaskStatus* pStatus = pTask ? pTask : (pNode ? (SStmTaskStatus*)pNode->data : taosArrayGet(pTasks, i));
693,876✔
977
    TAOS_CHECK_EXIT(msmSTAddToVgroupMapImpl(streamId, pStatus, trigReader));
693,876✔
978
    if (pNode) {
693,876✔
979
      pNode = TD_DLIST_NODE_NEXT(pNode);
380,340✔
980
    }
981
  }
982
  
983
_exit:
476,320✔
984

985
  if (code) {
476,320✔
986
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
987
  }
988
  
989
  return code;
476,320✔
990
}
991

992

993
static int32_t msmSTAddToSnodeMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SStmTaskStatus* pTask, int32_t taskNum, int32_t deployId) {
813,018✔
994
  int32_t code = TSDB_CODE_SUCCESS;
813,018✔
995
  int32_t lino = 0;
813,018✔
996
  int32_t rtaskNum = (taskNum > 0) ? taskNum : taosArrayGetSize(pTasks);
813,018✔
997
  int32_t taskType = (deployId < 0) ? STREAM_TRIGGER_TASK : STREAM_RUNNER_TASK;
813,018✔
998
  
999
  for (int32_t i = 0; i < rtaskNum; ++i) {
1,734,075✔
1000
    SStmTaskStatus* pStatus = (taskNum > 0) ? (pTask + i) : taosArrayGet(pTasks, i);
921,057✔
1001
    TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pStatus, deployId));
921,057✔
1002
  }
1003
  
1004
_exit:
813,018✔
1005

1006
  if (code) {
813,018✔
1007
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1008
  }
1009

1010
  return code;
813,018✔
1011
}
1012

1013
int64_t msmAssignTaskId(void) {
1,614,555✔
1014
  return atomic_fetch_add_64(&mStreamMgmt.lastTaskId, 1);
1,614,555✔
1015
}
1016

1017
int64_t msmAssignTaskSeriousId(void) {
1,614,555✔
1018
  return taosGetTimestampNs();
1,614,555✔
1019
}
1020

1021

1022
int32_t msmIsSnodeAlive(SMnode* pMnode, int32_t snodeId, int64_t streamId, bool* alive) {
1,084,815✔
1023
  int32_t code = TSDB_CODE_SUCCESS;
1,084,815✔
1024
  int32_t lino = 0;
1,084,815✔
1025
  bool     noExists = false;
1,084,815✔
1026
  SStmSnodeStatus* pStatus = NULL;
1,084,815✔
1027

1028
  while (true) {
1029
    pStatus = taosHashGet(mStreamMgmt.snodeMap, &snodeId, sizeof(snodeId));
1,097,496✔
1030
    if (NULL == pStatus) {
1,097,496✔
1031
      if (noExists) {
12,681✔
1032
        mstsError("snode %d not exists in snodeMap", snodeId);
×
1033
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1034
      }
1035

1036
      noExists = true;
12,681✔
1037
      TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pMnode));
12,681✔
1038
      
1039
      continue;
12,681✔
1040
    }
1041

1042
    *alive = (pStatus->runnerThreadNum >= 0);
1,084,815✔
1043
    break;
1,084,815✔
1044
  }
1045

1046
_exit:
1,084,815✔
1047

1048
  if (code) {
1,084,815✔
1049
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1050
  }
1051

1052
  return code;
1,084,815✔
1053
}
1054

1055
int32_t msmRetrieveStaticSnodeId(SMnode* pMnode, SStreamObj* pStream) {
422,998✔
1056
  int32_t code = TSDB_CODE_SUCCESS;
422,998✔
1057
  int32_t lino = 0;
422,998✔
1058
  bool alive = false;
422,998✔
1059
  int32_t mainSnodeId = atomic_load_32(&pStream->mainSnodeId);
422,998✔
1060
  int32_t snodeId = mainSnodeId;
422,998✔
1061
  int64_t streamId = pStream->pCreate->streamId;
422,998✔
1062
  
1063
  while (true) {
1064
    TAOS_CHECK_EXIT(msmIsSnodeAlive(pMnode, snodeId, streamId, &alive));
422,998✔
1065

1066
    if (alive) {
422,998✔
1067
      return snodeId;
422,998✔
1068
    }
1069
    
1070
    if (snodeId == mainSnodeId) {
×
1071
      SSnodeObj* pSnode = mndAcquireSnode(pMnode, snodeId);
×
1072
      if (NULL == pSnode) {
×
1073
        stsWarn("snode %d not longer exists, ignore assign snode", snodeId);
×
1074
        return 0;
×
1075
      }
1076
      
1077
      if (pSnode->replicaId <= 0) {
×
1078
        mstsError("no available snode now, mainSnodeId:%d, replicaId:%d", mainSnodeId, pSnode->replicaId);
×
1079
        mndReleaseSnode(pMnode, pSnode);
×
1080
        return 0;
×
1081
      }
1082

1083
      snodeId = pSnode->replicaId;
×
1084
      mndReleaseSnode(pMnode, pSnode);
×
1085
      
1086
      continue;
×
1087
    }
1088

1089
    mstsError("no available snode now, mainSnodeId:%d, followerSnodeId:%d", mainSnodeId, snodeId);
×
1090
    return 0;
×
1091
  }
1092

1093
_exit:
×
1094

1095
  if (code) {
×
1096
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1097
  }
1098

1099
  return 0;
×
1100
}
1101

1102
int32_t msmAssignRandomSnodeId(SMnode* pMnode, int64_t streamId) {
643,706✔
1103
  int32_t code = TSDB_CODE_SUCCESS;
643,706✔
1104
  int32_t lino = 0;
643,706✔
1105
  int32_t snodeIdx = 0;
643,706✔
1106
  int32_t snodeId = 0;
643,706✔
1107
  void      *pIter = NULL;
643,706✔
1108
  SSnodeObj *pObj = NULL;
643,706✔
1109
  bool alive = false;
643,706✔
1110
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
643,706✔
1111
  if (snodeNum <= 0) {
643,706✔
1112
    mstsInfo("no available snode now, num:%d", snodeNum);
2,720✔
1113
    goto _exit;
2,720✔
1114
  }
1115

1116
  int32_t snodeTarget = taosRand() % snodeNum;
640,986✔
1117

1118
  while (1) {
1119
    pIter = sdbFetch(pMnode->pSdb, SDB_SNODE, pIter, (void **)&pObj);
661,817✔
1120
    if (pIter == NULL) {
661,817✔
1121
      if (0 == snodeId) {
×
1122
        mstsError("no alive snode now, snodeNum:%d", snodeNum);
×
1123
        break;
×
1124
      }
1125
      
1126
      snodeId = 0;
×
1127
      continue;
×
1128
    }
1129

1130
    code = msmIsSnodeAlive(pMnode, pObj->id, streamId, &alive);
661,817✔
1131
    if (code) {
661,817✔
1132
      sdbRelease(pMnode->pSdb, pObj);
×
1133
      sdbCancelFetch(pMnode->pSdb, pIter);
×
1134
      pObj = NULL;
×
1135
      TAOS_CHECK_EXIT(code);
×
1136
    }
1137
    
1138
    if (!alive) {
661,817✔
1139
      sdbRelease(pMnode->pSdb, pObj);
×
1140
      continue;
×
1141
    }
1142

1143
    snodeId = pObj->id;
661,817✔
1144
    if (snodeIdx == snodeTarget) {
661,817✔
1145
      sdbRelease(pMnode->pSdb, pObj);
640,986✔
1146
      sdbCancelFetch(pMnode->pSdb, pIter);
640,986✔
1147
      pObj = NULL;
640,986✔
1148
      goto _exit;
640,986✔
1149
    }
1150

1151
    sdbRelease(pMnode->pSdb, pObj);
20,831✔
1152
    snodeIdx++;
20,831✔
1153
  }
1154

1155
_exit:
643,706✔
1156

1157
  if (code) {
643,706✔
1158
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1159
  }
1160

1161
  if (0 == snodeId) {
643,706✔
1162
    terrno = TSDB_CODE_SNODE_NO_AVAILABLE_NODE;
2,720✔
1163
  }
1164

1165
  return snodeId;
643,706✔
1166
}
1167

1168
int32_t msmAssignTaskSnodeId(SMnode* pMnode, SStreamObj* pStream, bool isStatic) {
856,890✔
1169
  int64_t streamId = pStream->pCreate->streamId;
856,890✔
1170
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
856,890✔
1171
  int32_t snodeId = 0;
856,890✔
1172
  if (snodeNum <= 0) {
856,890✔
1173
    mstsInfo("no available snode now, num:%d", snodeNum);
×
1174
    goto _exit;
×
1175
  }
1176

1177
  snodeId = isStatic ? msmRetrieveStaticSnodeId(pMnode, pStream) : msmAssignRandomSnodeId(pMnode, streamId);
856,890✔
1178

1179
_exit:
856,890✔
1180

1181
  if (0 == snodeId) {
856,890✔
1182
    terrno = TSDB_CODE_SNODE_NO_AVAILABLE_NODE;
×
1183
  }
1184

1185
  return snodeId;
856,890✔
1186
}
1187

1188

1189
static int32_t msmBuildTriggerTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
205,674✔
1190
  int32_t code = TSDB_CODE_SUCCESS;
205,674✔
1191
  int32_t lino = 0;
205,674✔
1192
  int64_t streamId = pStream->pCreate->streamId;
205,674✔
1193

1194
  pInfo->triggerTask = taosMemoryCalloc(1, sizeof(SStmTaskStatus));
205,674✔
1195
  TSDB_CHECK_NULL(pInfo->triggerTask, code, lino, _exit, terrno);
205,674✔
1196

1197
  pInfo->triggerTask->id.taskId = pCtx->triggerTaskId;
205,674✔
1198
  pInfo->triggerTask->id.deployId = 0;
205,674✔
1199
  pInfo->triggerTask->id.seriousId = msmAssignTaskSeriousId();
205,674✔
1200
  pInfo->triggerTask->id.nodeId = pCtx->triggerNodeId;
205,674✔
1201
  pInfo->triggerTask->id.taskIdx = 0;
205,674✔
1202
  pInfo->triggerTask->type = STREAM_TRIGGER_TASK;
205,674✔
1203
  pInfo->triggerTask->lastUpTs = pCtx->currTs;
205,674✔
1204
  pInfo->triggerTask->pStream = pInfo;
205,674✔
1205

1206
  SStmTaskDeploy info = {0};
205,674✔
1207
  info.task.type = pInfo->triggerTask->type;
205,674✔
1208
  info.task.streamId = streamId;
205,674✔
1209
  info.task.taskId =  pInfo->triggerTask->id.taskId;
205,674✔
1210
  info.task.seriousId = pInfo->triggerTask->id.seriousId;
205,674✔
1211
  info.task.nodeId =  pInfo->triggerTask->id.nodeId;
205,674✔
1212
  info.task.taskIdx =  pInfo->triggerTask->id.taskIdx;
205,674✔
1213
  TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pInfo, &info, pStream));
205,674✔
1214
  TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
205,674✔
1215
  
1216
  (void)atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
205,674✔
1217

1218
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pInfo->triggerTask));
205,674✔
1219
  TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, pInfo->triggerTask, 1, -1));
205,674✔
1220

1221
_exit:
205,674✔
1222

1223
  if (code) {
205,674✔
1224
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1225
  }
1226

1227
  return code;
205,674✔
1228
}
1229

1230
static int32_t msmTDAddSingleTrigReader(SStmGrpCtx* pCtx, SStmTaskStatus* pState, int32_t nodeId, SStmStatus* pInfo, int64_t streamId) {
311,072✔
1231
  int32_t code = TSDB_CODE_SUCCESS;
311,072✔
1232
  int32_t lino = 0;
311,072✔
1233

1234
  pState->id.taskId = msmAssignTaskId();
311,072✔
1235
  pState->id.deployId = 0;
311,072✔
1236
  pState->id.seriousId = msmAssignTaskSeriousId();
311,072✔
1237
  pState->id.nodeId = nodeId;
311,072✔
1238
  pState->id.taskIdx = 0;
311,072✔
1239
  pState->type = STREAM_READER_TASK;
311,072✔
1240
  pState->flags = STREAM_FLAG_TRIGGER_READER;
311,072✔
1241
  pState->status = STREAM_STATUS_UNDEPLOYED;
311,072✔
1242
  pState->lastUpTs = pCtx->currTs;
311,072✔
1243
  pState->pStream = pInfo;
311,072✔
1244
  
1245
  SStmTaskDeploy info = {0};
311,072✔
1246
  info.task.type = pState->type;
311,072✔
1247
  info.task.streamId = streamId;
311,072✔
1248
  info.task.taskId = pState->id.taskId;
311,072✔
1249
  info.task.flags = pState->flags;
311,072✔
1250
  info.task.seriousId = pState->id.seriousId;
311,072✔
1251
  info.task.nodeId = pState->id.nodeId;
311,072✔
1252
  info.task.taskIdx = pState->id.taskIdx;
311,072✔
1253
  TAOS_CHECK_EXIT(msmBuildReaderDeployInfo(&info, NULL, pInfo, true));
311,072✔
1254
  TAOS_CHECK_EXIT(msmTDAddToVgroupMap(mStreamMgmt.toDeployVgMap, &info, streamId));
311,072✔
1255

1256
_exit:
311,072✔
1257

1258
  if (code) {
311,072✔
1259
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1260
  }
1261

1262
  return code;
311,072✔
1263
}
1264

1265
static int32_t msmTDAddTrigReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
205,674✔
1266
  int32_t code = TSDB_CODE_SUCCESS;
205,674✔
1267
  int32_t lino = 0;
205,674✔
1268
  int64_t streamId = pStream->pCreate->streamId;
205,674✔
1269
  SSdb   *pSdb = pCtx->pMnode->pSdb;
205,674✔
1270
  SStmTaskStatus* pState = NULL;
205,674✔
1271
  SVgObj *pVgroup = NULL;
205,674✔
1272
  SDbObj* pDb = NULL;
205,674✔
1273
  
1274
  switch (pStream->pCreate->triggerTblType) {
205,674✔
1275
    case TSDB_NORMAL_TABLE:
119,130✔
1276
    case TSDB_CHILD_TABLE:
1277
    case TSDB_VIRTUAL_CHILD_TABLE:
1278
    case TSDB_VIRTUAL_NORMAL_TABLE: {
1279
      pInfo->trigReaders = taosArrayInit_s(sizeof(SStmTaskStatus), 1);
119,130✔
1280
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
119,130✔
1281
      pState = taosArrayGet(pInfo->trigReaders, 0);
119,130✔
1282
      
1283
      TAOS_CHECK_EXIT(msmTDAddSingleTrigReader(pCtx, pState, pStream->pCreate->triggerTblVgId, pInfo, streamId));
119,130✔
1284
      break;
119,130✔
1285
    }
1286
    case TSDB_SUPER_TABLE: {
82,264✔
1287
      pDb = mndAcquireDb(pCtx->pMnode, pStream->pCreate->triggerDB);
82,264✔
1288
      if (NULL == pDb) {
82,264✔
1289
        code = terrno;
×
1290
        mstsError("failed to acquire db %s, error:%s", pStream->pCreate->triggerDB, terrstr());
×
1291
        goto _exit;
×
1292
      }
1293

1294
      pInfo->trigReaders = taosArrayInit(pDb->cfg.numOfVgroups, sizeof(SStmTaskStatus));
82,264✔
1295
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
82,264✔
1296
      
1297
      void *pIter = NULL;
82,264✔
1298
      while (1) {
418,959✔
1299
        SStmTaskDeploy info = {0};
501,223✔
1300
        pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
501,223✔
1301
        if (pIter == NULL) {
501,223✔
1302
          break;
82,264✔
1303
        }
1304
      
1305
        if (pVgroup->dbUid == pDb->uid && !pVgroup->isTsma) {
418,959✔
1306
          pState = taosArrayReserve(pInfo->trigReaders, 1);
129,434✔
1307

1308
          code = msmTDAddSingleTrigReader(pCtx, pState, pVgroup->vgId, pInfo, streamId);
129,434✔
1309
          if (code) {
129,434✔
1310
            sdbRelease(pSdb, pVgroup);
×
1311
            sdbCancelFetch(pSdb, pIter);
×
1312
            pVgroup = NULL;
×
1313
            TAOS_CHECK_EXIT(code);
×
1314
          }
1315
        }
1316

1317
        sdbRelease(pSdb, pVgroup);
418,959✔
1318
      }
1319
      break;
82,264✔
1320
    }
1321
    default:
4,280✔
1322
      mstsDebug("%s ignore triggerTblType %d", __FUNCTION__, pStream->pCreate->triggerTblType);
4,280✔
1323
      break;
4,280✔
1324
  }
1325

1326
_exit:
205,674✔
1327

1328
  mndReleaseDb(pCtx->pMnode, pDb);
205,674✔
1329

1330
  if (code) {
205,674✔
1331
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1332
  }
1333

1334
  return code;
205,674✔
1335
}
1336

1337
int32_t msmUPAddScanTask(SStmGrpCtx* pCtx, SStreamObj* pStream, char* scanPlan, int32_t vgId, int64_t taskId) {
380,718✔
1338
  int32_t code = TSDB_CODE_SUCCESS;
380,718✔
1339
  int32_t lino = 0;
380,718✔
1340
  SSubplan* pSubplan = NULL;
380,718✔
1341
  int64_t streamId = pStream->pCreate->streamId;
380,718✔
1342
  int64_t key[2] = {streamId, 0};
380,718✔
1343
  SStmTaskSrcAddr addr;
380,260✔
1344
  TAOS_CHECK_EXIT(nodesStringToNode(scanPlan, (SNode**)&pSubplan));
380,718✔
1345
  addr.isFromCache = false;
380,718✔
1346
  
1347
  if (MNODE_HANDLE == vgId) {
380,718✔
1348
    mndGetMnodeEpSet(pCtx->pMnode, &addr.epset);
×
1349
  } else if (vgId > MNODE_HANDLE) {
380,718✔
1350
    addr.epset = mndGetVgroupEpsetById(pCtx->pMnode, vgId);
380,718✔
1351
  } else {
1352
    mstsError("invalid vgId %d in scanPlan", vgId);
×
1353
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1354
  }
1355
  
1356
  addr.taskId = taskId;
380,718✔
1357
  addr.vgId = vgId;
380,718✔
1358
  addr.groupId = pSubplan->id.groupId;
380,718✔
1359

1360
  key[1] = pSubplan->id.subplanId;
380,718✔
1361

1362
  SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
380,718✔
1363
  if (NULL == ppRes) {
380,718✔
1364
    SArray* pRes = taosArrayInit(1, sizeof(addr));
360,944✔
1365
    TSDB_CHECK_NULL(pRes, code, lino, _exit, terrno);
360,944✔
1366
    TSDB_CHECK_NULL(taosArrayPush(pRes, &addr), code, lino, _exit, terrno);
721,888✔
1367
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.toUpdateScanMap, key, sizeof(key), &pRes, POINTER_BYTES));
360,944✔
1368
  } else {
1369
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &addr), code, lino, _exit, terrno);
39,548✔
1370
  }
1371

1372
  mstsDebug("calcReader %" PRIx64 " added to toUpdateScan, vgId:%d, groupId:%d, subplanId:%d", taskId, vgId, pSubplan->id.groupId, pSubplan->id.subplanId);
380,718✔
1373
  
1374
  (void)atomic_add_fetch_32(&mStreamMgmt.toUpdateScanNum, 1);
380,718✔
1375
  
1376
_exit:
380,718✔
1377

1378
  nodesDestroyNode((SNode*)pSubplan);
380,718✔
1379

1380
  if (code) {
380,718✔
1381
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1382
  }
1383

1384
  return code;
380,718✔
1385
}
1386

1387
int32_t msmUPAddCacheTask(SStmGrpCtx* pCtx, SStreamCalcScan* pScan, SStreamObj* pStream) {
82,728✔
1388
  int32_t code = TSDB_CODE_SUCCESS;
82,728✔
1389
  int32_t lino = 0;
82,728✔
1390
  SSubplan* pSubplan = NULL;
82,728✔
1391
  int64_t streamId = pStream->pCreate->streamId;
82,728✔
1392
  int64_t key[2] = {streamId, 0};
82,728✔
1393
  TAOS_CHECK_EXIT(nodesStringToNode(pScan->scanPlan, (SNode**)&pSubplan));
82,728✔
1394

1395
  SStmTaskSrcAddr addr;
82,728✔
1396
  addr.isFromCache = true;
82,728✔
1397
  addr.epset = mndGetDnodeEpsetById(pCtx->pMnode, pCtx->triggerNodeId);
82,728✔
1398
  addr.taskId = pCtx->triggerTaskId;
82,728✔
1399
  addr.vgId = pCtx->triggerNodeId;
82,728✔
1400
  addr.groupId = pSubplan->id.groupId;
82,728✔
1401

1402
  key[1] = pSubplan->id.subplanId;
82,728✔
1403
  SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
82,728✔
1404
  if (NULL == ppRes) {
82,728✔
1405
    SArray* pRes = taosArrayInit(1, sizeof(addr));
82,728✔
1406
    TSDB_CHECK_NULL(pRes, code, lino, _exit, terrno);
82,728✔
1407
    TSDB_CHECK_NULL(taosArrayPush(pRes, &addr), code, lino, _exit, terrno);
165,456✔
1408
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.toUpdateScanMap, key, sizeof(key), &pRes, POINTER_BYTES));
82,728✔
1409
  } else {
1410
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &addr), code, lino, _exit, terrno);
×
1411
  }
1412
  
1413
  (void)atomic_add_fetch_32(&mStreamMgmt.toUpdateScanNum, 1);
82,728✔
1414
  
1415
_exit:
82,728✔
1416

1417
  nodesDestroyNode((SNode*)pSubplan);
82,728✔
1418
  
1419
  if (code) {
82,728✔
1420
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1421
  }
1422

1423
  return code;
82,728✔
1424
}
1425

1426

1427
static int32_t msmTDAddSingleCalcReader(SStmGrpCtx* pCtx, SStmTaskStatus* pState, int32_t taskIdx, int32_t nodeId, void* calcScanPlan, SStmStatus* pInfo, int64_t streamId) {
382,804✔
1428
  int32_t code = TSDB_CODE_SUCCESS;
382,804✔
1429
  int32_t lino = 0;
382,804✔
1430

1431
  TAOS_CHECK_EXIT(mstGetScanUidFromPlan(streamId, calcScanPlan, &pState->id.uid));
382,804✔
1432

1433
  pState->id.taskId = msmAssignTaskId();
382,804✔
1434
  pState->id.deployId = 0;
382,804✔
1435
  pState->id.seriousId = msmAssignTaskSeriousId();
382,804✔
1436
  pState->id.nodeId = nodeId;
382,804✔
1437
  pState->id.taskIdx = taskIdx;
382,804✔
1438
  pState->type = STREAM_READER_TASK;
382,804✔
1439
  pState->flags = 0;
382,804✔
1440
  pState->status = STREAM_STATUS_UNDEPLOYED;
382,804✔
1441
  pState->lastUpTs = pCtx->currTs;
382,804✔
1442
  pState->pStream = pInfo;
382,804✔
1443
  
1444
  SStmTaskDeploy info = {0};
382,804✔
1445
  info.task.type = pState->type;
382,804✔
1446
  info.task.streamId = streamId;
382,804✔
1447
  info.task.taskId = pState->id.taskId;
382,804✔
1448
  info.task.flags = pState->flags;
382,804✔
1449
  info.task.seriousId = pState->id.seriousId;
382,804✔
1450
  info.task.nodeId = pState->id.nodeId;
382,804✔
1451
  info.task.taskIdx = pState->id.taskIdx;
382,804✔
1452
  TAOS_CHECK_EXIT(msmBuildReaderDeployInfo(&info, calcScanPlan, pInfo, false));
382,804✔
1453
  TAOS_CHECK_EXIT(msmTDAddToVgroupMap(mStreamMgmt.toDeployVgMap, &info, streamId));
382,804✔
1454

1455
_exit:
382,804✔
1456

1457
  if (code) {
382,804✔
1458
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1459
  }
1460

1461
  return code;
382,804✔
1462
}
1463

1464

1465
static int32_t msmTDAddCalcReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
205,674✔
1466
  int32_t code = TSDB_CODE_SUCCESS;
205,674✔
1467
  int32_t lino = 0;
205,674✔
1468
  int32_t calcTasksNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
205,674✔
1469
  int64_t streamId = pStream->pCreate->streamId;
205,674✔
1470
  SStmTaskStatus* pState = NULL;
205,674✔
1471
  pInfo->calcReaders = tdListNew(sizeof(SStmTaskStatus));
205,674✔
1472
  TSDB_CHECK_NULL(pInfo->calcReaders, code, lino, _exit, terrno);
205,674✔
1473

1474
  
1475
  for (int32_t i = 0; i < calcTasksNum; ++i) {
668,742✔
1476
    SStreamCalcScan* pScan = taosArrayGet(pInfo->pCreate->calcScanPlanList, i);
463,068✔
1477
    if (pScan->readFromCache) {
463,068✔
1478
      TAOS_CHECK_EXIT(msmUPAddCacheTask(pCtx, pScan, pStream));
82,728✔
1479
      continue;
82,728✔
1480
    }
1481
    
1482
    int32_t vgNum = taosArrayGetSize(pScan->vgList);
380,340✔
1483
    for (int32_t m = 0; m < vgNum; ++m) {
760,680✔
1484
      pState = tdListReserve(pInfo->calcReaders);
380,340✔
1485
      TSDB_CHECK_NULL(pState, code, lino, _exit, terrno);
380,340✔
1486

1487
      TAOS_CHECK_EXIT(msmTDAddSingleCalcReader(pCtx, pState, i, *(int32_t*)taosArrayGet(pScan->vgList, m), pScan->scanPlan, pInfo, streamId));
380,340✔
1488
      TAOS_CHECK_EXIT(msmUPAddScanTask(pCtx, pStream, pScan->scanPlan, pState->id.nodeId, pState->id.taskId));
380,340✔
1489
    }
1490
  }
1491

1492
_exit:
205,674✔
1493

1494
  if (code) {
205,674✔
1495
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1496
  }
1497

1498
  return code;
205,674✔
1499
}
1500

1501

1502

1503
static int32_t msmUPPrepareReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
378✔
1504
  int32_t code = TSDB_CODE_SUCCESS;
378✔
1505
  int32_t lino = 0;
378✔
1506
  int64_t streamId = pStream->pCreate->streamId;
378✔
1507
  int32_t calcTasksNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
378✔
1508
  if (calcTasksNum <= 0) {
378✔
1509
    mstsDebug("no calc scan plan, ignore parepare reader tasks, readerNum:%d", (int32_t)MST_LIST_SIZE(pInfo->calcReaders));
×
1510
    return code;    
×
1511
  }
1512
  
1513
  SListNode* pNode = listHead(pInfo->calcReaders);
378✔
1514
  
1515
  for (int32_t i = 0; i < calcTasksNum; ++i) {
756✔
1516
    SStreamCalcScan* pScan = taosArrayGet(pStream->pCreate->calcScanPlanList, i);
378✔
1517
    if (pScan->readFromCache) {
378✔
1518
      TAOS_CHECK_EXIT(msmUPAddCacheTask(pCtx, pScan, pStream));
×
1519
      continue;
×
1520
    }
1521
    
1522
    int32_t vgNum = taosArrayGetSize(pScan->vgList);
378✔
1523
    for (int32_t m = 0; m < vgNum; ++m) {
756✔
1524
      SStmTaskStatus* pReader = (SStmTaskStatus*)pNode->data;
378✔
1525
      TAOS_CHECK_EXIT(msmUPAddScanTask(pCtx, pStream, pScan->scanPlan, pReader->id.nodeId, pReader->id.taskId));
378✔
1526
      pNode = TD_DLIST_NODE_NEXT(pNode);
378✔
1527
    }
1528
  }
1529

1530
_exit:
378✔
1531

1532
  if (code) {
378✔
1533
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1534
  }
1535

1536
  return code;
378✔
1537
}
1538

1539
static int32_t msmBuildReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
205,674✔
1540
  int32_t code = TSDB_CODE_SUCCESS;
205,674✔
1541
  int32_t lino = 0;
205,674✔
1542
  int64_t streamId = pStream->pCreate->streamId;
205,674✔
1543
  
1544
  TAOS_CHECK_EXIT(msmTDAddTrigReaderTasks(pCtx, pInfo, pStream));
205,674✔
1545
  TAOS_CHECK_EXIT(msmTDAddCalcReaderTasks(pCtx, pInfo, pStream));
205,674✔
1546

1547
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, pInfo->trigReaders, NULL, NULL));
205,674✔
1548
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, pInfo->calcReaders, NULL));
205,674✔
1549
  
1550
  TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, pInfo->trigReaders, NULL, NULL, true));
205,674✔
1551
  TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, pInfo->calcReaders, NULL, false));
205,674✔
1552
  
1553
_exit:
205,674✔
1554

1555
  if (code) {
205,674✔
1556
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1557
  }
1558
  
1559
  return code;
205,674✔
1560
}
1561

1562
int32_t msmUpdatePlanSourceAddr(SStreamTask* pTask, int64_t streamId, SSubplan* plan, int64_t clientId, SStmTaskSrcAddr* pSrc, int32_t msgType, int64_t srcSubplanId) {
1,580,043✔
1563
  SDownstreamSourceNode source = {
1,580,043✔
1564
      .type = QUERY_NODE_DOWNSTREAM_SOURCE,
1565
      .clientId = clientId,
1566
      .taskId = pSrc->taskId,
1,580,043✔
1567
      .sId = 0,
1568
      .execId = 0,
1569
      .fetchMsgType = msgType,
1570
      .localExec = false,
1571
  };
1572

1573
  source.addr.epSet = pSrc->epset;
1,580,043✔
1574
  source.addr.nodeId = pSrc->vgId;
1,580,043✔
1575

1576
  msttDebug("try to update subplan %d grp %d sourceAddr from subplan %" PRId64 ", clientId:%" PRIx64 ", srcTaskId:%" PRIx64 ", srcNodeId:%d, msgType:%s", 
1,580,043✔
1577
      plan->id.subplanId, pSrc->groupId, srcSubplanId, source.clientId, source.taskId, source.addr.nodeId, TMSG_INFO(source.fetchMsgType));
1578
  
1579
  return qSetSubplanExecutionNode(plan, pSrc->groupId, &source);
1,580,043✔
1580
}
1581

1582
int32_t msmGetTaskIdFromSubplanId(SStreamObj* pStream, SArray* pRunners, int32_t beginIdx, int32_t subplanId, int64_t* taskId, SStreamTask** ppParent) {
64,167✔
1583
  int64_t streamId = pStream->pCreate->streamId;
64,167✔
1584
  int32_t runnerNum = taosArrayGetSize(pRunners);
64,167✔
1585
  for (int32_t i = beginIdx; i < runnerNum; ++i) {
197,439✔
1586
    SStmTaskDeploy* pDeploy = taosArrayGet(pRunners, i);
197,439✔
1587
    SSubplan* pPlan = pDeploy->msg.runner.pPlan;
197,439✔
1588
    if (pPlan->id.subplanId == subplanId) {
197,439✔
1589
      *taskId = pDeploy->task.taskId;
64,167✔
1590
      *ppParent = &pDeploy->task;
64,167✔
1591
      return TSDB_CODE_SUCCESS;
64,167✔
1592
    }
1593
  }
1594

1595
  mstsError("subplanId %d not found in runner list", subplanId);
×
1596

1597
  return TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
1598
}
1599

1600
int32_t msmUpdateLowestPlanSourceAddr(SSubplan* pPlan, SStmTaskDeploy* pDeploy, int64_t streamId) {
715,383✔
1601
  int32_t code = TSDB_CODE_SUCCESS;
715,383✔
1602
  int32_t lino = 0;
715,383✔
1603
  int64_t key[2] = {streamId, -1};
715,383✔
1604
  SNode* pNode = NULL;
715,383✔
1605
  SStreamTask* pTask = &pDeploy->task;
715,383✔
1606
  FOREACH(pNode, pPlan->pChildren) {
2,169,132✔
1607
    if (QUERY_NODE_VALUE != nodeType(pNode)) {
1,453,749✔
1608
      msttDebug("node type %d is not valueNode, skip it", nodeType(pNode));
64,167✔
1609
      continue;
64,167✔
1610
    }
1611
    
1612
    SValueNode* pVal = (SValueNode*)pNode;
1,389,582✔
1613
    if (TSDB_DATA_TYPE_BIGINT != pVal->node.resType.type) {
1,389,582✔
1614
      msttWarn("invalid value node data type %d for runner's child subplan", pVal->node.resType.type);
×
1615
      continue;
×
1616
    }
1617

1618
    key[1] = MND_GET_RUNNER_SUBPLANID(pVal->datum.i);
1,389,582✔
1619

1620
    SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
1,389,582✔
1621
    if (NULL == ppRes) {
1,389,582✔
1622
      msttError("lowest runner subplan ID:%d,%d can't get its child ID:%" PRId64 " addr", pPlan->id.groupId, pPlan->id.subplanId, key[1]);
×
1623
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1624
    }
1625

1626
    int32_t childrenNum = taosArrayGetSize(*ppRes);
1,389,582✔
1627
    for (int32_t i = 0; i < childrenNum; ++i) {
2,905,458✔
1628
      SStmTaskSrcAddr* pAddr = taosArrayGet(*ppRes, i);
1,515,876✔
1629
      TAOS_CHECK_EXIT(msmUpdatePlanSourceAddr(pTask, streamId, pPlan, pDeploy->task.taskId, pAddr, pAddr->isFromCache ? TDMT_STREAM_FETCH_FROM_CACHE : TDMT_STREAM_FETCH, key[1]));
1,515,876✔
1630
    }
1631
  }
1632

1633
_exit:
715,383✔
1634

1635
  if (code) {
715,383✔
1636
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1637
  }
1638

1639
  return code;
715,383✔
1640
}
1641

1642
int32_t msmUpdateRunnerPlan(SStmGrpCtx* pCtx, SArray* pRunners, int32_t beginIdx, SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
715,383✔
1643
  int32_t code = TSDB_CODE_SUCCESS;
715,383✔
1644
  int32_t lino = 0;
715,383✔
1645
  SSubplan* pPlan = pDeploy->msg.runner.pPlan;
715,383✔
1646
  SStreamTask* pTask = &pDeploy->task;
715,383✔
1647
  SStreamTask* parentTask = NULL;
715,383✔
1648
  int64_t streamId = pStream->pCreate->streamId;
715,383✔
1649

1650
  TAOS_CHECK_EXIT(msmUpdateLowestPlanSourceAddr(pPlan, pDeploy, streamId));
715,383✔
1651

1652
  SNode* pTmp = NULL;
715,383✔
1653
  WHERE_EACH(pTmp, pPlan->pChildren) {
2,169,132✔
1654
    if (QUERY_NODE_VALUE == nodeType(pTmp)) {
1,453,749✔
1655
      ERASE_NODE(pPlan->pChildren);
1,389,582✔
1656
      continue;
1,389,582✔
1657
    }
1658
    WHERE_NEXT;
64,167✔
1659
  }
1660
  nodesClearList(pPlan->pChildren);
715,383✔
1661
  pPlan->pChildren = NULL;
715,383✔
1662

1663
  if (NULL == pPlan->pParents) {
715,383✔
1664
    goto _exit;
651,216✔
1665
  }
1666

1667
  SNode* pNode = NULL;
64,167✔
1668
  int64_t parentTaskId = 0;
64,167✔
1669
  SStmTaskSrcAddr addr = {0};
64,167✔
1670
  addr.taskId = pDeploy->task.taskId;
64,167✔
1671
  addr.vgId = pDeploy->task.nodeId;
64,167✔
1672
  addr.groupId = pPlan->id.groupId;
64,167✔
1673
  addr.epset = mndGetDnodeEpsetById(pCtx->pMnode, pDeploy->task.nodeId);
64,167✔
1674
  FOREACH(pNode, pPlan->pParents) {
128,334✔
1675
    SSubplan* pSubplan = (SSubplan*)pNode;
64,167✔
1676
    TAOS_CHECK_EXIT(msmGetTaskIdFromSubplanId(pStream, pRunners, beginIdx, pSubplan->id.subplanId, &parentTaskId, &parentTask));
64,167✔
1677
    TAOS_CHECK_EXIT(msmUpdatePlanSourceAddr(parentTask, streamId, pSubplan, parentTaskId, &addr, TDMT_STREAM_FETCH_FROM_RUNNER, pPlan->id.subplanId));
64,167✔
1678
  }
1679
  
1680
_exit:
714,066✔
1681

1682
  if (code) {
715,383✔
1683
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1684
  }
1685

1686
  return code;
715,383✔
1687
}
1688

1689
int32_t msmUpdateRunnerPlans(SStmGrpCtx* pCtx, SArray* pRunners, SStreamObj* pStream) {
651,216✔
1690
  int32_t code = TSDB_CODE_SUCCESS;
651,216✔
1691
  int32_t lino = 0;
651,216✔
1692
  int64_t streamId = pStream->pCreate->streamId;
651,216✔
1693
  int32_t runnerNum = taosArrayGetSize(pRunners);
651,216✔
1694
  
1695
  for (int32_t i = 0; i < runnerNum; ++i) {
1,366,599✔
1696
    SStmTaskDeploy* pDeploy = taosArrayGet(pRunners, i);
715,383✔
1697
    TAOS_CHECK_EXIT(msmUpdateRunnerPlan(pCtx, pRunners, i, pDeploy, pStream));
715,383✔
1698
    TAOS_CHECK_EXIT(nodesNodeToString((SNode*)pDeploy->msg.runner.pPlan, false, (char**)&pDeploy->msg.runner.pPlan, NULL));
715,383✔
1699

1700
    SStreamTask* pTask = &pDeploy->task;
715,383✔
1701
    msttDebugL("runner updated task plan:%s", (const char*)pDeploy->msg.runner.pPlan);
715,383✔
1702
  }
1703

1704
_exit:
651,216✔
1705

1706
  if (code) {
651,216✔
1707
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1708
  }
1709

1710
  return code;
651,216✔
1711
}
1712

1713
static int32_t msmBuildRunnerTasksImpl(SStmGrpCtx* pCtx, int32_t dagIdx, SStmStatus* pInfo, SStreamObj* pStream, SQueryPlan** pRoot, SNodeList** subEP) {
216,946✔
1714
  int32_t code = 0;
216,946✔
1715
  int32_t lino = 0;
216,946✔
1716
  int64_t streamId = pStream->pCreate->streamId;
216,946✔
1717
  SArray* deployTaskList = NULL;
216,946✔
1718
  SArray* deployList = NULL;
216,946✔
1719
  int32_t deployNodeId = 0;
216,946✔
1720
  SStmTaskStatus* pState = NULL;
216,946✔
1721
  int32_t taskIdx = 0;
216,946✔
1722
  SNodeListNode *plans = NULL;
216,946✔
1723
  SQueryPlan    *pDag = NULL;
216,946✔
1724
  int32_t        taskNum = 0;
216,946✔
1725
  int32_t        totalTaskNum = 0;
216,946✔
1726
  bool           subQ = false;
216,946✔
1727

1728
  if (dagIdx >= 0) {
216,946✔
1729
    subQ = true;
14,624✔
1730
    pDag = (SQueryPlan *)nodesListGetNode((*pRoot)->pChildren, dagIdx);
14,624✔
1731
  } else {
1732
    pDag = *pRoot;
202,322✔
1733
  }
1734

1735
  if (pDag->numOfSubplans <= 0) {
216,946✔
1736
    mstsError("invalid subplan num:%d", pDag->numOfSubplans);
×
1737
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1738
  }
1739

1740
  if ((*pRoot)->numOfSubplans != pStream->pCreate->numOfCalcSubplan) {
216,946✔
1741
    mstsError("numOfCalcSubplan %d mismatch with numOfSubplans %d", pStream->pCreate->numOfCalcSubplan, pDag->numOfSubplans);
×
1742
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1743
  }
1744

1745
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
216,946✔
1746
  if (levelNum <= 0) {
216,946✔
1747
    mstsError("invalid level num:%d", levelNum);
×
1748
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1749
  }
1750

1751
  int32_t        lowestLevelIdx = levelNum - 1;
216,946✔
1752
  
1753
  plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, 0);
216,946✔
1754
  if (QUERY_NODE_NODE_LIST != nodeType(plans)) {
216,946✔
1755
    mstsError("invalid level plan, level:0, planNodeType:%d", nodeType(plans));
×
1756
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1757
  }
1758
  
1759
  taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
216,946✔
1760
  if (taskNum != 1) {
216,946✔
1761
    mstsError("invalid level plan number:%d, level:0", taskNum);
×
1762
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1763
  }
1764

1765
  deployTaskList = taosArrayInit_s(sizeof(SStmTaskDeploy), pDag->numOfSubplans);
216,946✔
1766
  TSDB_CHECK_NULL(deployTaskList, code, lino, _exit, terrno);
216,946✔
1767
  
1768
  for (int32_t deployId = 0; deployId < pInfo->runnerDeploys; ++deployId) {
867,784✔
1769
    totalTaskNum = 0;
650,838✔
1770

1771
    deployList = pInfo->runners[deployId];
650,838✔
1772
    deployNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, (0 == deployId) ? true : false);
650,838✔
1773
    if (!GOT_SNODE(deployNodeId)) {
650,838✔
1774
      TAOS_CHECK_EXIT(terrno);
×
1775
    }
1776

1777
    taskIdx = 0;
650,838✔
1778

1779
    for (int32_t i = lowestLevelIdx; i >= 0; --i) {
1,324,416✔
1780
      plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
673,578✔
1781
      if (NULL == plans) {
673,578✔
1782
        mstsError("empty level plan, level:%d", i);
×
1783
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1784
      }
1785

1786
      if (QUERY_NODE_NODE_LIST != nodeType(plans)) {
673,578✔
1787
        mstsError("invalid level plan, level:%d, planNodeType:%d", i, nodeType(plans));
×
1788
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1789
      }
1790

1791
      taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
673,578✔
1792
      if (taskNum <= 0) {
673,578✔
1793
        mstsError("invalid level plan number:%d, level:%d", taskNum, i);
×
1794
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1795
      }
1796

1797
      totalTaskNum += taskNum;
673,578✔
1798
      if (totalTaskNum > pDag->numOfSubplans) {
673,578✔
1799
        mstsError("current totalTaskNum %d is bigger than numOfSubplans %d, level:%d", totalTaskNum, pDag->numOfSubplans, i);
×
1800
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1801
      }
1802

1803
      for (int32_t n = 0; n < taskNum; ++n) {
1,388,583✔
1804
        SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
715,005✔
1805
        pState = taosArrayReserve(deployList, 1);
715,005✔
1806

1807
        pState->id.taskId = msmAssignTaskId();
715,005✔
1808
        pState->id.deployId = deployId;
715,005✔
1809
        pState->id.seriousId = msmAssignTaskSeriousId();
715,005✔
1810
        pState->id.nodeId = deployNodeId;
715,005✔
1811
        pState->id.taskIdx = MND_SET_RUNNER_TASKIDX(i, n);
715,005✔
1812
        pState->type = STREAM_RUNNER_TASK;
715,005✔
1813
        pState->flags = (0 == i) ? STREAM_FLAG_TOP_RUNNER : 0;
715,005✔
1814
        pState->status = STREAM_STATUS_UNDEPLOYED;
715,005✔
1815
        pState->lastUpTs = pCtx->currTs;
715,005✔
1816
        pState->pStream = pInfo;
715,005✔
1817

1818
        SStmTaskDeploy* pDeploy = taosArrayGet(deployTaskList, taskIdx++);
715,005✔
1819
        pDeploy->task.type = pState->type;
715,005✔
1820
        pDeploy->task.streamId = streamId;
715,005✔
1821
        pDeploy->task.taskId = pState->id.taskId;
715,005✔
1822
        pDeploy->task.flags = pState->flags;
715,005✔
1823
        pDeploy->task.seriousId = pState->id.seriousId;
715,005✔
1824
        pDeploy->task.deployId = pState->id.deployId;
715,005✔
1825
        pDeploy->task.nodeId = pState->id.nodeId;
715,005✔
1826
        pDeploy->task.taskIdx = pState->id.taskIdx;
715,005✔
1827
        TAOS_CHECK_EXIT(msmBuildRunnerDeployInfo(pDeploy, plan, pStream, pInfo, 0 == i && !subQ));
715,005✔
1828

1829
        SStreamTask* pTask = &pDeploy->task;
715,005✔
1830
        msttDebug("runner task deploy built, subplan level:%d, taskIdx:%d, groupId:%d, subplanId:%d",
715,005✔
1831
            i, pTask->taskIdx, plan->id.groupId, plan->id.subplanId);
1832

1833
        if (subQ) {
715,005✔
1834
          if (i == 0) {
61,980✔
1835
            SStmTaskSrcAddr addr = {0};
43,872✔
1836
            SDownstreamSourceNode* pSource = NULL;
43,872✔
1837

1838
            TAOS_CHECK_EXIT(nodesMakeNode(QUERY_NODE_DOWNSTREAM_SOURCE, (SNode**)&pSource));
43,872✔
1839

1840
            addr.taskId = pDeploy->task.taskId;
43,872✔
1841
            addr.vgId = pDeploy->task.nodeId;
43,872✔
1842
            addr.groupId = plan->id.groupId;
43,872✔
1843
            addr.epset = mndGetDnodeEpsetById(pCtx->pMnode, pDeploy->task.nodeId);
43,872✔
1844

1845
            pSource->addr.epSet = addr.epset;
43,872✔
1846
            pSource->addr.nodeId = addr.vgId;
43,872✔
1847

1848
            pSource->clientId = streamId;
43,872✔
1849
            pSource->taskId = pDeploy->task.taskId;
43,872✔
1850
            pSource->sId = 0;
43,872✔
1851
            pSource->execId = 0;
43,872✔
1852
            pSource->fetchMsgType = TDMT_STREAM_FETCH_FROM_RUNNER;
43,872✔
1853
            pSource->localExec = false;
43,872✔
1854

1855
            TAOS_CHECK_EXIT(nodesListMakeStrictAppend(subEP, (SNode *)pSource));
43,872✔
1856
          }
1857
        } else {
1858
          TAOS_CHECK_EXIT(nodesCloneList(*subEP, &plan->pSubQ));
653,025✔
1859
        }
1860
      }
1861

1862
      mstsDebug("deploy %d level %d initialized, taskNum:%d", deployId, i, taskNum);
673,578✔
1863
    }
1864

1865
    if (totalTaskNum != pDag->numOfSubplans) {
650,838✔
1866
      mstsError("totalTaskNum %d mis-match with numOfSubplans %d", totalTaskNum, pDag->numOfSubplans);
×
1867
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1868
    }
1869

1870
    TAOS_CHECK_EXIT(msmUpdateRunnerPlans(pCtx, deployTaskList, pStream));
650,838✔
1871

1872
    TAOS_CHECK_EXIT(msmTDAddRunnersToSnodeMap(deployTaskList, pStream));
650,838✔
1873

1874
    nodesDestroyNode((SNode *)(*pRoot));
650,838✔
1875
    *pRoot = NULL;
650,838✔
1876
    
1877
    TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)pRoot));
650,838✔
1878
    if (subQ) {
650,838✔
1879
      pDag = (SQueryPlan *)nodesListGetNode((*pRoot)->pChildren, dagIdx);
43,872✔
1880
    } else {
1881
      pDag = *pRoot;
606,966✔
1882
    }
1883

1884
    mstsDebug("total %d runner tasks added for deploy %d", totalTaskNum, deployId);
650,838✔
1885
  }
1886

1887
  if (!subQ) {
216,946✔
1888
    for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
809,288✔
1889
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, pInfo->runners[i], NULL, NULL));
606,966✔
1890
      TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, pInfo->runners[i], NULL, 0, i));
606,966✔
1891
    }
1892
  }
1893
  
1894
  pInfo->runnerNum += totalTaskNum;
216,946✔
1895
  
1896
_exit:
216,946✔
1897

1898
  if (code) {
216,946✔
1899
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1900
  }
1901

1902
  taosArrayDestroy(deployTaskList);
216,946✔
1903

1904
  return code;
216,946✔
1905
}
1906

1907
int32_t msmReBuildRunnerTasks(SStmGrpCtx* pCtx, SQueryPlan* pDag, SStmStatus* pInfo, SStreamObj* pStream, SStmTaskAction* pAction) {
378✔
1908
  int32_t code = 0;
378✔
1909
  int32_t lino = 0;
378✔
1910
  int64_t streamId = pStream->pCreate->streamId;
378✔
1911
  int32_t newNodeId = 0;
378✔
1912
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
378✔
1913
  int32_t        lowestLevelIdx = levelNum - 1;
378✔
1914
  SNodeListNode *plans = NULL;
378✔
1915
  int32_t        taskNum = 0;
378✔
1916
  int32_t        totalTaskNum = 0;
378✔
1917
  int32_t        deployId = 0;
378✔
1918
  SStmTaskStatus* pRunner = NULL;
378✔
1919
  SStmTaskStatus* pStartRunner = NULL;
378✔
1920
  int32_t taskIdx = 0;
378✔
1921
  SArray* deployTaskList = taosArrayInit_s(sizeof(SStmTaskDeploy), pDag->numOfSubplans);
378✔
1922
  TSDB_CHECK_NULL(deployTaskList, code, lino, _exit, terrno);
378✔
1923

1924
  for (int32_t r = 0; r < pAction->deployNum; ++r) {
756✔
1925
    deployId = pAction->deployId[r];
378✔
1926

1927
    pRunner = taosArrayGet(pInfo->runners[deployId], 0);
378✔
1928

1929
    pStartRunner = pRunner;
378✔
1930
    totalTaskNum = 0;
378✔
1931

1932
    newNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, (0 == r) ? true : false);
378✔
1933
    if (!GOT_SNODE(newNodeId)) {
378✔
1934
      TAOS_CHECK_EXIT(terrno);
×
1935
    }
1936

1937
    taskIdx = 0;
378✔
1938
    
1939
    for (int32_t i = lowestLevelIdx; i >= 0; --i) {
756✔
1940
      plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
378✔
1941
      taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
378✔
1942
      totalTaskNum += taskNum;
378✔
1943

1944
      pRunner->flags &= STREAM_FLAG_REDEPLOY_RUNNER;
378✔
1945
      
1946
      for (int32_t n = 0; n < taskNum; ++n) {
756✔
1947
        SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
378✔
1948

1949
        int32_t newTaskIdx = MND_SET_RUNNER_TASKIDX(i, n);
378✔
1950
        if (pRunner->id.taskIdx != newTaskIdx) {
378✔
1951
          mstsError("runner TASK:%" PRId64 " taskIdx %d mismatch with newTaskIdx:%d", pRunner->id.taskId, pRunner->id.taskIdx, newTaskIdx);
×
1952
          TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
1953
        }
1954

1955
        pRunner->id.nodeId = newNodeId;
378✔
1956

1957
        SStmTaskDeploy* pDeploy = taosArrayGet(deployTaskList, taskIdx++);
378✔
1958
        pDeploy->task.type = pRunner->type;
378✔
1959
        pDeploy->task.streamId = streamId;
378✔
1960
        pDeploy->task.taskId = pRunner->id.taskId;
378✔
1961
        pDeploy->task.flags = pRunner->flags;
378✔
1962
        pDeploy->task.seriousId = pRunner->id.seriousId;
378✔
1963
        pDeploy->task.nodeId = pRunner->id.nodeId;
378✔
1964
        pDeploy->task.taskIdx = pRunner->id.taskIdx;
378✔
1965
        TAOS_CHECK_EXIT(msmBuildRunnerDeployInfo(pDeploy, plan, pStream, pInfo, 0 == i));
378✔
1966

1967
        pRunner++;
378✔
1968
      }
1969

1970
      mstsDebug("level %d initialized, taskNum:%d", i, taskNum);
378✔
1971
    }
1972

1973
    TAOS_CHECK_EXIT(msmUpdateRunnerPlans(pCtx, deployTaskList, pStream));
378✔
1974

1975
    TAOS_CHECK_EXIT(msmTDAddRunnersToSnodeMap(deployTaskList, pStream));
378✔
1976

1977
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, pInfo->runners[deployId], NULL, 0, deployId));
378✔
1978

1979
    nodesDestroyNode((SNode *)pDag);
378✔
1980
    pDag = NULL;
378✔
1981

1982
    TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pDag));
378✔
1983
  }
1984

1985
_exit:
378✔
1986

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

1991
  nodesDestroyNode((SNode *)pDag);
378✔
1992
  taosArrayDestroy(deployTaskList);
378✔
1993

1994
  return code;
378✔
1995
}
1996

1997

1998
int32_t msmSetStreamRunnerExecReplica(int64_t streamId, SStmStatus* pInfo) {
194,490✔
1999
  int32_t code = TSDB_CODE_SUCCESS;
194,490✔
2000
  int32_t lino = 0;
194,490✔
2001
  //STREAMTODO 
2002
  
2003
  pInfo->runnerDeploys = MND_STREAM_RUNNER_DEPLOY_NUM;
194,490✔
2004
  pInfo->runnerReplica = MND_STREAM_RUNNER_REPLICA_NUM;
194,490✔
2005

2006
_exit:
194,490✔
2007

2008
  if (code) {
194,490✔
2009
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2010
  }
2011

2012
  return code;
194,490✔
2013
}
2014

2015

2016
static int32_t msmUpdateCalcReaderTasks(SStreamObj* pStream, SNodeList* pSubEP) {
202,322✔
2017
  int32_t   code = TSDB_CODE_SUCCESS;
202,322✔
2018
  int32_t   lino = 0;
202,322✔
2019
  int64_t   streamId = pStream->pCreate->streamId;
202,322✔
2020
  void*     pIter = NULL;
202,322✔
2021
  SSubplan* pSubplan = NULL;
202,322✔
2022

2023
  while ((pIter = taosHashIterate(mStreamMgmt.toDeployVgMap, pIter))) {
854,805✔
2024
    SStmVgTasksToDeploy* pVg = (SStmVgTasksToDeploy*)pIter;
652,483✔
2025
    (void)mstWaitLock(&pVg->lock, true);
652,483✔
2026

2027
    int32_t taskNum = taosArrayGetSize(pVg->taskList);
652,483✔
2028
    if (atomic_load_32(&pVg->deployed) == taskNum) {
652,483✔
2029
      taosRUnLockLatch(&pVg->lock);
×
2030
      continue;
×
2031
    }
2032

2033
    for (int32_t i = 0; i < taskNum; ++i) {
5,793,805✔
2034
      SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, i);
5,141,322✔
2035
      if (pExt->deployed || pExt->deploy.task.streamId != streamId || STREAM_READER_TASK != pExt->deploy.task.type) {
5,141,322✔
2036
        continue;
4,516,020✔
2037
      }
2038

2039
      if (!pExt->deploy.msg.reader.triggerReader) {
625,302✔
2040
        SStreamReaderDeployFromCalc* pCalcReaderDeploy = &pExt->deploy.msg.reader.msg.calc;
380,340✔
2041
        TAOS_CHECK_EXIT(nodesStringToNode(pCalcReaderDeploy->calcScanPlan, (SNode**)&pSubplan));
380,340✔
2042
        TAOS_CHECK_EXIT(nodesCloneList(pSubEP, &pSubplan->pSubQ));
380,340✔
2043
        
2044
        // Free old calcScanPlan before nodesNodeToString overwrites the pointer
2045
        if (pCalcReaderDeploy->freeScanPlan) {
380,340✔
2046
          taosMemoryFreeClear(pCalcReaderDeploy->calcScanPlan);
380,340✔
2047
        }
2048
        TAOS_CHECK_EXIT(nodesNodeToString((SNode*)pSubplan, false, (char**)&pCalcReaderDeploy->calcScanPlan, NULL));
380,340✔
2049
        pCalcReaderDeploy->freeScanPlan = true;
380,340✔
2050
        nodesDestroyNode((SNode *)pSubplan);
380,340✔
2051
      }
2052
    }
2053

2054
    taosRUnLockLatch(&pVg->lock);
652,483✔
2055
  }
2056

2057
_exit:
202,322✔
2058
  if (code) {
202,322✔
UNCOV
2059
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2060
  }
2061

2062
  return code;
202,322✔
2063
}
2064

2065
static int32_t msmBuildRunnerTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
205,674✔
2066
  if (NULL == pStream->pCreate->calcPlan) {
205,674✔
2067
    return TSDB_CODE_SUCCESS;
3,352✔
2068
  }
2069

2070
  int32_t code = TSDB_CODE_SUCCESS;
202,322✔
2071
  int32_t lino = 0;
202,322✔
2072
  int64_t streamId = pStream->pCreate->streamId;
202,322✔
2073
  SQueryPlan* pPlan = NULL;
202,322✔
2074
  SNodeList*  pSubEP = NULL;
202,322✔
2075
  SNode*      pNode = NULL;
202,322✔
2076
  int32_t     subQueryPlans = 0;
202,322✔
2077

2078
  TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pPlan));
202,322✔
2079

2080
  FOREACH(pNode, pPlan->pChildren) {
216,946✔
2081
    SQueryPlan *calcSubQPlan = (SQueryPlan *)pNode;
14,624✔
2082

2083
    subQueryPlans += calcSubQPlan->numOfSubplans;
14,624✔
2084
  }
2085

2086
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
809,288✔
2087
    pInfo->runners[i] = taosArrayInit(pPlan->numOfSubplans + subQueryPlans, sizeof(SStmTaskStatus));
606,966✔
2088
    TSDB_CHECK_NULL(pInfo->runners[i], code, lino, _exit, terrno);
606,966✔
2089
  }
2090

2091
  for (int32_t i = 0; i < LIST_LENGTH(pPlan->pChildren); ++i) {
216,946✔
2092
    code = msmBuildRunnerTasksImpl(pCtx, i, pInfo, pStream, &pPlan, &pSubEP);
14,624✔
2093
    TAOS_CHECK_EXIT(code);
14,624✔
2094
  }
2095

2096
  code = msmBuildRunnerTasksImpl(pCtx, -1, pInfo, pStream, &pPlan, &pSubEP);
202,322✔
2097
  TAOS_CHECK_EXIT(code);
202,322✔
2098

2099
  taosHashClear(mStreamMgmt.toUpdateScanMap);
202,322✔
2100
  mStreamMgmt.toUpdateScanNum = 0;
202,322✔
2101

2102
  TAOS_CHECK_EXIT(msmUpdateCalcReaderTasks(pStream, pSubEP));
202,322✔
2103

2104
_exit:
202,322✔
2105
  nodesDestroyNode((SNode *)pPlan);
202,322✔
2106
  if (pSubEP) {
202,322✔
2107
    nodesDestroyList(pSubEP);
12,846✔
2108
  }
2109

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

2114
  return code;
202,322✔
2115
}
2116

2117
static int32_t msmBuildStreamTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
205,674✔
2118
  int32_t code = TSDB_CODE_SUCCESS;
205,674✔
2119
  int32_t lino = 0;
205,674✔
2120
  int64_t streamId = pStream->pCreate->streamId;
205,674✔
2121

2122
  mstsInfo("start to deploy stream tasks, deployTimes:%" PRId64, pInfo->deployTimes);
205,674✔
2123

2124
  pCtx->triggerTaskId = msmAssignTaskId();
205,674✔
2125
  pCtx->triggerNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
205,674✔
2126
  if (!GOT_SNODE(pCtx->triggerNodeId)) {
205,674✔
2127
    TAOS_CHECK_EXIT(terrno);
×
2128
  }
2129

2130
  TAOS_CHECK_EXIT(msmBuildReaderTasks(pCtx, pInfo, pStream));
205,674✔
2131
  TAOS_CHECK_EXIT(msmBuildRunnerTasks(pCtx, pInfo, pStream));
205,674✔
2132
  TAOS_CHECK_EXIT(msmBuildTriggerTasks(pCtx, pInfo, pStream));
205,674✔
2133
  
2134
_exit:
205,674✔
2135

2136
  if (code) {
205,674✔
UNCOV
2137
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2138
  }
2139

2140
  return code;
205,674✔
2141
}
2142

2143
static int32_t msmInitTrigReaderList(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
×
2144
  int32_t code = TSDB_CODE_SUCCESS;
×
2145
  int32_t lino = 0;
×
2146
  int64_t streamId = pStream->pCreate->streamId;
×
2147
  SSdb   *pSdb = pCtx->pMnode->pSdb;
×
2148
  SStmTaskStatus* pState = NULL;
×
2149
  SDbObj* pDb = NULL;
×
2150
  
2151
  switch (pStream->pCreate->triggerTblType) {
×
2152
    case TSDB_NORMAL_TABLE:
×
2153
    case TSDB_CHILD_TABLE:
2154
    case TSDB_VIRTUAL_CHILD_TABLE:
2155
    case TSDB_VIRTUAL_NORMAL_TABLE: {
2156
      pInfo->trigReaders = taosArrayInit_s(sizeof(SStmTaskStatus), 1);
×
2157
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
×
2158
      pInfo->trigReaderNum = 1;
×
2159
      break;
×
2160
    }
2161
    case TSDB_SUPER_TABLE: {
×
2162
      pDb = mndAcquireDb(pCtx->pMnode, pStream->pCreate->triggerDB);
×
2163
      if (NULL == pDb) {
×
2164
        code = terrno;
×
2165
        mstsError("failed to acquire db %s, error:%s", pStream->pCreate->triggerDB, terrstr());
×
2166
        goto _exit;
×
2167
      }
2168

2169
      pInfo->trigReaders = taosArrayInit(pDb->cfg.numOfVgroups, sizeof(SStmTaskStatus));
×
2170
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
×
2171
      pInfo->trigReaderNum = pDb->cfg.numOfVgroups;
×
2172
      mndReleaseDb(pCtx->pMnode, pDb);
×
2173
      pDb = NULL;
×
2174
      break;
×
2175
    }
2176
    default:
×
2177
      pInfo->trigReaderNum = 0;
×
2178
      mstsDebug("%s ignore triggerTblType %d", __FUNCTION__, pStream->pCreate->triggerTblType);
×
2179
      break;
×
2180
  }
2181

2182
_exit:
×
2183

2184
  if (code) {
×
2185
    mndReleaseDb(pCtx->pMnode, pDb);
×
2186
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2187
  }
2188

2189
  return code;
×
2190
}
2191

2192

2193
static int32_t msmInitStmStatus(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStreamObj* pStream, bool initList) {
197,842✔
2194
  int32_t code = TSDB_CODE_SUCCESS;
197,842✔
2195
  int32_t lino = 0;
197,842✔
2196
  int64_t streamId = pStream->pCreate->streamId;
197,842✔
2197

2198
  pStatus->lastActionTs = INT64_MIN;
197,842✔
2199

2200
  if (NULL == pStatus->streamName) {
197,842✔
2201
    pStatus->streamName = taosStrdup(pStream->name);
197,842✔
2202
    TSDB_CHECK_NULL(pStatus->streamName, code, lino, _exit, terrno);
197,842✔
2203
  }
2204

2205
  TAOS_CHECK_EXIT(tCloneStreamCreateDeployPointers(pStream->pCreate, &pStatus->pCreate));
197,842✔
2206
  
2207
  if (pStream->pCreate->numOfCalcSubplan > 0) {
197,842✔
2208
    pStatus->runnerNum = pStream->pCreate->numOfCalcSubplan;
194,490✔
2209
    
2210
    TAOS_CHECK_EXIT(msmSetStreamRunnerExecReplica(streamId, pStatus));
194,490✔
2211
  }
2212

2213
  if (initList) {
197,842✔
2214
    TAOS_CHECK_EXIT(msmInitTrigReaderList(pCtx, pStatus, pStream));
×
2215

2216
    int32_t subPlanNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
×
2217
    if (subPlanNum > 0) {
×
2218
      pStatus->calcReaderNum = subPlanNum;
×
2219
      pStatus->calcReaders = tdListNew(sizeof(SStmTaskStatus));
×
2220
      TSDB_CHECK_NULL(pStatus->calcReaders, code, lino, _exit, terrno);
×
2221
    }
2222

2223
    if (pStatus->runnerNum > 0) {
×
2224
      for (int32_t i = 0; i < pStatus->runnerDeploys; ++i) {
×
2225
        pStatus->runners[i] = taosArrayInit(pStatus->runnerNum, sizeof(SStmTaskStatus));
×
2226
        TSDB_CHECK_NULL(pStatus->runners[i], code, lino, _exit, terrno);
×
2227
      }
2228
    }
2229
  }
2230
  
2231
_exit:
197,842✔
2232

2233
  if (code) {
197,842✔
2234
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2235
  }
2236

2237
  return code;
197,842✔
2238
}
2239

2240
static int32_t msmDeployStreamTasks(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmStatus* pStatus) {
205,674✔
2241
  int32_t code = TSDB_CODE_SUCCESS;
205,674✔
2242
  int32_t lino = 0;
205,674✔
2243
  int64_t streamId = pStream->pCreate->streamId;
205,674✔
2244
  SStmStatus info = {0};
205,674✔
2245

2246
  if (NULL == pStatus) {
205,674✔
2247
    TAOS_CHECK_EXIT(msmInitStmStatus(pCtx, &info, pStream, false));
197,842✔
2248

2249
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.streamMap, &streamId, sizeof(streamId), &info, sizeof(info)));
197,842✔
2250

2251
    pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
197,842✔
2252
  }
2253
  
2254
  TAOS_CHECK_EXIT(msmBuildStreamTasks(pCtx, pStatus, pStream));
205,674✔
2255

2256
  mstLogSStmStatus("stream deployed", streamId, pStatus);
205,674✔
2257

2258
_exit:
205,674✔
2259

2260
  if (code) {
205,674✔
UNCOV
2261
    if (NULL != pStatus) {
×
UNCOV
2262
      msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
UNCOV
2263
      mstsError("stream build error:%s, will try to stop current stream", tstrerror(code));
×
2264
    }
2265
    
UNCOV
2266
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2267
  }
2268

2269
  return code;
205,674✔
2270
}
2271

2272

2273
static int32_t msmSTRemoveStream(int64_t streamId, bool fromStreamMap) {
8,843✔
2274
  int32_t code = TSDB_CODE_SUCCESS;
8,843✔
2275
  void* pIter = NULL;
8,843✔
2276

2277
  while ((pIter = taosHashIterate(mStreamMgmt.toDeployVgMap, pIter))) {
16,481✔
2278
    SStmVgTasksToDeploy* pVg = (SStmVgTasksToDeploy*)pIter;
7,638✔
2279
    (void)mstWaitLock(&pVg->lock, true);
7,638✔
2280

2281
    int32_t taskNum = taosArrayGetSize(pVg->taskList);
7,638✔
2282
    if (atomic_load_32(&pVg->deployed) == taskNum) {
7,638✔
2283
      taosRUnLockLatch(&pVg->lock);
×
2284
      continue;
×
2285
    }
2286

2287
    for (int32_t i = 0; i < taskNum; ++i) {
33,502✔
2288
      SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, i);
25,864✔
2289
      if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
25,864✔
2290
        continue;
25,360✔
2291
      }
2292

2293
      mstDestroySStmTaskToDeployExt(pExt);
504✔
2294
      pExt->deployed = true;
504✔
2295
    }
2296
    
2297
    taosRUnLockLatch(&pVg->lock);
7,638✔
2298
  }
2299

2300
  while ((pIter = taosHashIterate(mStreamMgmt.toDeploySnodeMap, pIter))) {
17,028✔
2301
    SStmSnodeTasksDeploy* pSnode = (SStmSnodeTasksDeploy*)pIter;
8,185✔
2302
    (void)mstWaitLock(&pSnode->lock, true);
8,185✔
2303

2304
    int32_t taskNum = taosArrayGetSize(pSnode->triggerList);
8,185✔
2305
    if (atomic_load_32(&pSnode->triggerDeployed) != taskNum) {
8,185✔
2306
      for (int32_t i = 0; i < taskNum; ++i) {
22,794✔
2307
        SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, i);
15,554✔
2308
        if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
15,554✔
2309
          continue;
14,924✔
2310
        }
2311
        
2312
        mstDestroySStmTaskToDeployExt(pExt);
630✔
2313
        pExt->deployed = true;
630✔
2314
      }
2315
    }
2316

2317
    taskNum = taosArrayGetSize(pSnode->runnerList);
8,185✔
2318
    if (atomic_load_32(&pSnode->runnerDeployed) != taskNum) {
8,185✔
2319
      for (int32_t i = 0; i < taskNum; ++i) {
56,359✔
2320
        SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, i);
48,174✔
2321
        if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
48,174✔
2322
          continue;
46,095✔
2323
        }
2324
        
2325
        mstDestroySStmTaskToDeployExt(pExt);
2,079✔
2326
        pExt->deployed = true;
2,079✔
2327
      }
2328
    }
2329

2330
    taosRUnLockLatch(&pSnode->lock);
8,185✔
2331
  }
2332

2333
  
2334
  while ((pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter))) {
24,490✔
2335
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
15,647✔
2336
    code = taosHashRemove(pSnode->streamTasks, &streamId, sizeof(streamId));
15,647✔
2337
    if (TSDB_CODE_SUCCESS == code) {
15,647✔
2338
      mstsDebug("stream removed from snodeMap %d, remainStreams:%d", *(int32_t*)taosHashGetKey(pIter, NULL), (int32_t)taosHashGetSize(pSnode->streamTasks));
9,410✔
2339
    }
2340
  }
2341

2342
  while ((pIter = taosHashIterate(mStreamMgmt.vgroupMap, pIter))) {
40,146✔
2343
    SStmVgroupStatus* pVg = (SStmVgroupStatus*)pIter;
31,303✔
2344
    code = taosHashRemove(pVg->streamTasks, &streamId, sizeof(streamId));
31,303✔
2345
    if (TSDB_CODE_SUCCESS == code) {
31,303✔
2346
      mstsDebug("stream removed from vgroupMap %d, remainStreams:%d", *(int32_t*)taosHashGetKey(pIter, NULL), (int32_t)taosHashGetSize(pVg->streamTasks));
13,132✔
2347
    }
2348
  }
2349

2350
  size_t keyLen = 0;
8,843✔
2351
  while ((pIter = taosHashIterate(mStreamMgmt.taskMap, pIter))) {
658,487✔
2352
    int64_t* pStreamId = taosHashGetKey(pIter, &keyLen);
649,644✔
2353
    if (*pStreamId == streamId) {
649,644✔
2354
      int64_t taskId = *(pStreamId + 1);
53,000✔
2355
      code = taosHashRemove(mStreamMgmt.taskMap, pStreamId, keyLen);
53,000✔
2356
      if (code) {
53,000✔
2357
        mstsError("TASK:%" PRIx64 " remove from taskMap failed, error:%s", taskId, tstrerror(code));
×
2358
      } else {
2359
        mstsDebug("TASK:%" PRIx64 " removed from taskMap", taskId);
53,000✔
2360
      }
2361
    }
2362
  }
2363

2364
  if (fromStreamMap) {
8,843✔
2365
    code = taosHashRemove(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
444✔
2366
    if (code) {
444✔
2367
      mstsError("stream remove from streamMap failed, error:%s", tstrerror(code));
×
2368
    } else {
2369
      mstsDebug("stream removed from streamMap, remains:%d", taosHashGetSize(mStreamMgmt.streamMap));
444✔
2370
    }
2371
  }
2372
  
2373
  return code;
8,843✔
2374
}
2375

2376
static void msmResetStreamForRedeploy(int64_t streamId, SStmStatus* pStatus) {
8,399✔
2377
  mstsInfo("try to reset stream for redeploy, stopped:%d, current deployTimes:%" PRId64, atomic_load_8(&pStatus->stopped), pStatus->deployTimes);
8,399✔
2378
  
2379
  (void)msmSTRemoveStream(streamId, false);  
8,399✔
2380

2381
  mstResetSStmStatus(pStatus);
8,399✔
2382

2383
  pStatus->deployTimes++;
8,399✔
2384
}
8,399✔
2385

2386
static int32_t msmLaunchStreamDeployAction(SStmGrpCtx* pCtx, SStmStreamAction* pAction) {
208,741✔
2387
  int32_t code = TSDB_CODE_SUCCESS;
208,741✔
2388
  int32_t lino = 0;
208,741✔
2389
  int64_t streamId = pAction->streamId;
208,741✔
2390
  char* streamName = pAction->streamName;
208,741✔
2391
  SStreamObj* pStream = NULL;
208,741✔
2392
  int8_t stopped = 0;
208,741✔
2393

2394
  SStmStatus* pStatus = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
208,741✔
2395
  if (pStatus) {
208,741✔
2396
    stopped = atomic_load_8(&pStatus->stopped);
8,399✔
2397
    if (0 == stopped) {
8,399✔
2398
      mstsDebug("stream %s will try to reset and redeploy it", pAction->streamName);
819✔
2399
      msmResetStreamForRedeploy(streamId, pStatus);
819✔
2400
    } else {
2401
      if (MST_IS_USER_STOPPED(stopped) && !pAction->userAction) {
7,580✔
2402
        mstsWarn("stream %s already stopped by user, stopped:%d, ignore deploy it", pAction->streamName, stopped);
×
2403
        return code;
×
2404
      }
2405
      
2406
      if (stopped == atomic_val_compare_exchange_8(&pStatus->stopped, stopped, 0)) {
7,580✔
2407
        mstsDebug("stream %s will try to reset and redeploy it from stopped %d", pAction->streamName, stopped);
7,580✔
2408
        msmResetStreamForRedeploy(streamId, pStatus);
7,580✔
2409
      }
2410
    }
2411
  }
2412

2413
  code = mndAcquireStream(pCtx->pMnode, streamName, &pStream);
208,741✔
2414
  if (TSDB_CODE_MND_STREAM_NOT_EXIST == code) {
208,741✔
2415
    mstsWarn("stream %s no longer exists, ignore deploy", streamName);
2,500✔
2416
    return TSDB_CODE_SUCCESS;
2,500✔
2417
  }
2418

2419
  TAOS_CHECK_EXIT(code);
206,241✔
2420

2421
  if (pStatus && pStream->pCreate->streamId != streamId) {
206,241✔
2422
    mstsWarn("stream %s already dropped by user, ignore deploy it", pAction->streamName);
×
2423
    atomic_store_8(&pStatus->stopped, 2);
×
2424
    mstsInfo("set stream %s stopped by user since streamId mismatch", streamName);
×
2425
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_EXIST);
×
2426
  }
2427

2428
  int8_t userStopped = atomic_load_8(&pStream->userStopped);
206,241✔
2429
  int8_t userDropped = atomic_load_8(&pStream->userDropped);
206,241✔
2430
  if (userStopped || userDropped) {
206,241✔
2431
    mstsWarn("stream %s is stopped %d or removing %d, ignore deploy", streamName, userStopped, userDropped);
567✔
2432
    goto _exit;
567✔
2433
  }
2434
  
2435
  TAOS_CHECK_EXIT(msmDeployStreamTasks(pCtx, pStream, pStatus));
205,674✔
2436

2437
_exit:
206,241✔
2438

2439
  mndReleaseStream(pCtx->pMnode, pStream);
206,241✔
2440

2441
  if (code) {
206,241✔
UNCOV
2442
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2443
  }
2444

2445
  return code;
206,241✔
2446
}
2447

2448
static int32_t msmReLaunchReaderTask(SStreamObj* pStream, SStmTaskAction* pAction, SStmStatus* pStatus) {
1,342✔
2449
  int32_t code = TSDB_CODE_SUCCESS;
1,342✔
2450
  int32_t lino = 0;
1,342✔
2451
  int64_t streamId = pAction->streamId;
1,342✔
2452
  SStmTaskStatus** ppTask = taosHashGet(mStreamMgmt.taskMap, &pAction->streamId, sizeof(pAction->streamId) + sizeof(pAction->id.taskId));
1,342✔
2453
  if (NULL == ppTask) {
1,342✔
2454
    mstsError("TASK:%" PRId64 " not in taskMap, remain:%d", pAction->id.taskId, taosHashGetSize(mStreamMgmt.taskMap));
×
2455
    TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
2456
  }
2457
  
2458
  SStmTaskDeploy info = {0};
1,342✔
2459
  info.task.type = pAction->type;
1,342✔
2460
  info.task.streamId = pAction->streamId;
1,342✔
2461
  info.task.taskId = pAction->id.taskId;
1,342✔
2462
  info.task.seriousId = (*ppTask)->id.seriousId;
1,342✔
2463
  info.task.nodeId = pAction->id.nodeId;
1,342✔
2464
  info.task.taskIdx = pAction->id.taskIdx;
1,342✔
2465
  
2466
  bool isTriggerReader = STREAM_IS_TRIGGER_READER(pAction->flag);
1,342✔
2467
  SStreamCalcScan* scanPlan = NULL;
1,342✔
2468
  if (!isTriggerReader) {
1,342✔
2469
    scanPlan = taosArrayGet(pStatus->pCreate->calcScanPlanList, pAction->id.taskIdx);
567✔
2470
    if (NULL == scanPlan) {
567✔
2471
      mstsError("fail to get TASK:%" PRId64 " scanPlan, taskIdx:%d, scanPlanNum:%zu", 
×
2472
          pAction->id.taskId, pAction->id.taskIdx, taosArrayGetSize(pStatus->pCreate->calcScanPlanList));
2473
      TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
2474
    }
2475
  }
2476
  
2477
  TAOS_CHECK_EXIT(msmBuildReaderDeployInfo(&info, scanPlan ? scanPlan->scanPlan : NULL, pStatus, isTriggerReader));
1,342✔
2478
  TAOS_CHECK_EXIT(msmTDAddToVgroupMap(mStreamMgmt.toDeployVgMap, &info, pAction->streamId));
1,342✔
2479

2480
_exit:
1,342✔
2481

2482
  if (code) {
1,342✔
2483
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2484
  }
2485

2486
  return code;
1,342✔
2487
}
2488

2489
/*
2490
static int32_t msmReLaunchTriggerTask(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmTaskAction* pAction, SStmStatus* pStatus) {
2491
  int32_t code = TSDB_CODE_SUCCESS;
2492
  int32_t lino = 0;
2493
  int64_t streamId = pAction->streamId;
2494
  SStmTaskStatus** ppTask = taosHashGet(mStreamMgmt.taskMap, &pAction->streamId, sizeof(pAction->streamId) + sizeof(pAction->id.taskId));
2495
  if (NULL == ppTask) {
2496
    mstsError("TASK:%" PRId64 " not in taskMap, remain:%d", pAction->id.taskId, taosHashGetSize(mStreamMgmt.taskMap));
2497
    TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
2498
  }
2499
  
2500
  (*ppTask)->id.nodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
2501
  if (!GOT_SNODE((*ppTask)->id.nodeId)) {
2502
    mstsError("no avaible snode for deploying trigger task, seriousId: %" PRId64, (*ppTask)->id.seriousId);
2503
    return TSDB_CODE_SUCCESS;
2504
  }
2505
  
2506
  SStmTaskDeploy info = {0};
2507
  info.task.type = pAction->type;
2508
  info.task.streamId = streamId;
2509
  info.task.taskId = pAction->id.taskId;
2510
  info.task.seriousId = (*ppTask)->id.seriousId;
2511
  info.task.nodeId = (*ppTask)->id.nodeId;
2512
  info.task.taskIdx = pAction->id.taskIdx;
2513
  
2514
  TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pStatus, &info, pStream));
2515
  TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
2516
  TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, *ppTask, 1, -1));
2517
  
2518
  atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
2519

2520
_exit:
2521

2522
  if (code) {
2523
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
2524
  }
2525

2526
  return code;
2527
}
2528
*/
2529

2530
static int32_t msmReLaunchRunnerDeploy(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmTaskAction* pAction, SStmStatus* pStatus) {
378✔
2531
  int32_t code = TSDB_CODE_SUCCESS;
378✔
2532
  int32_t lino = 0;
378✔
2533
  int64_t streamId = pAction->streamId;
378✔
2534
  
2535
/*
2536
  if (pAction->triggerStatus) {
2537
    pCtx->triggerTaskId = pAction->triggerStatus->id.taskId;
2538
    pAction->triggerStatus->id.nodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
2539
    if (!GOT_SNODE(pAction->triggerStatus->id.nodeId)) {
2540
      mstsError("no avaible snode for deploying trigger task, seriousId:%" PRId64, pAction->triggerStatus->id.seriousId);
2541
      return TSDB_CODE_SUCCESS;
2542
    }
2543
  
2544
    pCtx->triggerNodeId = pAction->triggerStatus->id.nodeId;
2545
  } else {
2546
*/
2547
  pCtx->triggerTaskId = pStatus->triggerTask->id.taskId;
378✔
2548
  pCtx->triggerNodeId = pStatus->triggerTask->id.nodeId;
378✔
2549
//  }
2550
  
2551
  TAOS_CHECK_EXIT(msmUPPrepareReaderTasks(pCtx, pStatus, pStream));
378✔
2552
  
2553
  SQueryPlan* pPlan = NULL;
378✔
2554
  TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pPlan));
378✔
2555
  
2556
  TAOS_CHECK_EXIT(msmReBuildRunnerTasks(pCtx, pPlan, pStatus, pStream, pAction));
378✔
2557
  
2558
  taosHashClear(mStreamMgmt.toUpdateScanMap);
378✔
2559
  mStreamMgmt.toUpdateScanNum = 0;
378✔
2560
  
2561
/*
2562
  if (pAction->triggerStatus) {
2563
    SStmTaskDeploy info = {0};
2564
    info.task.type = STREAM_TRIGGER_TASK;
2565
    info.task.streamId = streamId;
2566
    info.task.taskId = pCtx->triggerTaskId;
2567
    info.task.seriousId = pAction->triggerStatus->id.seriousId;
2568
    info.task.nodeId = pCtx->triggerNodeId;
2569
    info.task.taskIdx = 0;
2570
  
2571
    TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pStatus, &info, pStream));
2572
    TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
2573
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, pAction->triggerStatus, 1, -1));
2574
    
2575
    atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
2576
  }
2577
*/
2578

2579
_exit:
378✔
2580

2581
  if (code) {
378✔
2582
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2583
  }
2584

2585
  return code;
378✔
2586
}
2587

2588

2589
static int32_t msmLaunchTaskDeployAction(SStmGrpCtx* pCtx, SStmTaskAction* pAction) {
1,720✔
2590
  int32_t code = TSDB_CODE_SUCCESS;
1,720✔
2591
  int32_t lino = 0;
1,720✔
2592
  int64_t streamId = pAction->streamId;
1,720✔
2593
  int64_t taskId = pAction->id.taskId;
1,720✔
2594
  SStreamObj* pStream = NULL;
1,720✔
2595

2596
  mstsDebug("start to handle stream tasks action, action task type:%s", gStreamTaskTypeStr[pAction->type]);
1,720✔
2597

2598
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &pAction->streamId, sizeof(pAction->streamId));
1,720✔
2599
  if (NULL == pStatus) {
1,720✔
2600
    mstsWarn("stream not in streamMap, remain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
2601
    return TSDB_CODE_SUCCESS;
×
2602
  }
2603

2604
  int8_t stopped = atomic_load_8(&pStatus->stopped);
1,720✔
2605
  if (stopped) {
1,720✔
2606
    mstsWarn("stream %s is already stopped %d, ignore task deploy", pStatus->streamName, stopped);
×
2607
    return TSDB_CODE_SUCCESS;
×
2608
  }
2609

2610
  code = mndAcquireStream(pCtx->pMnode, pStatus->streamName, &pStream);
1,720✔
2611
  if (TSDB_CODE_MND_STREAM_NOT_EXIST == code) {
1,720✔
2612
    mstsWarn("stream %s no longer exists, ignore task deploy", pStatus->streamName);
×
2613
    return TSDB_CODE_SUCCESS;
×
2614
  }
2615

2616
  TAOS_CHECK_EXIT(code);
1,720✔
2617

2618
  int8_t userStopped = atomic_load_8(&pStream->userStopped);
1,720✔
2619
  int8_t userDropped = atomic_load_8(&pStream->userDropped);
1,720✔
2620
  if (userStopped || userDropped) {
1,720✔
2621
    mstsWarn("stream %s is stopped %d or removing %d, ignore task deploy", pStatus->streamName, userStopped, userDropped);
×
2622
    goto _exit;
×
2623
  }
2624

2625
  switch (pAction->type) {
1,720✔
2626
    case STREAM_READER_TASK:
1,342✔
2627
      TAOS_CHECK_EXIT(msmReLaunchReaderTask(pStream, pAction, pStatus));
1,342✔
2628
      break;
1,342✔
2629
/*
2630
    case STREAM_TRIGGER_TASK:
2631
      TAOS_CHECK_EXIT(msmReLaunchTriggerTask(pCtx, pStream, pAction, pStatus));
2632
      break;
2633
*/
2634
    case STREAM_RUNNER_TASK:
378✔
2635
      if (pAction->multiRunner) {
378✔
2636
        TAOS_CHECK_EXIT(msmReLaunchRunnerDeploy(pCtx, pStream, pAction, pStatus));
378✔
2637
      } else {
2638
        mstsError("runner TASK:%" PRId64 " requires relaunch", pAction->id.taskId);
×
2639
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
2640
      }
2641
      break;
378✔
2642
    default:
×
2643
      mstsError("TASK:%" PRId64 " invalid task type:%d", pAction->id.taskId, pAction->type);
×
2644
      TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
2645
      break;
×
2646
  }
2647

2648
_exit:
1,720✔
2649

2650
  if (pStream) {
1,720✔
2651
    mndReleaseStream(pCtx->pMnode, pStream);
1,720✔
2652
  }
2653

2654
  if (code) {
1,720✔
2655
    msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
2656
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2657
  }
2658

2659
  return code;
1,720✔
2660
}
2661

2662
static int32_t msmTDRemoveStream(int64_t streamId) {
×
2663
  void* pIter = NULL;
×
2664
  
2665
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
×
2666
    while ((pIter = taosHashIterate(mStreamMgmt.toDeployVgMap, pIter))) {
×
2667
      SStmVgTasksToDeploy* pVg = (SStmVgTasksToDeploy*)pIter;
×
2668
      int32_t taskNum = taosArrayGetSize(pVg->taskList);
×
2669
      if (atomic_load_32(&pVg->deployed) == taskNum) {
×
2670
        continue;
×
2671
      }
2672
      
2673
      for (int32_t i = 0; i < taskNum; ++i) {
×
2674
        SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, i);
×
2675
        if (pExt->deploy.task.streamId == streamId && !pExt->deployed) {
×
2676
          pExt->deployed = true;
×
2677
        }
2678
      }
2679
    }
2680
  }
2681

2682
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0) {
×
2683
    while ((pIter = taosHashIterate(mStreamMgmt.toDeploySnodeMap, pIter))) {
×
2684
      SStmSnodeTasksDeploy* pSnode = (SStmSnodeTasksDeploy*)pIter;
×
2685
      int32_t taskNum = taosArrayGetSize(pSnode->triggerList);
×
2686
      if (atomic_load_32(&pSnode->triggerDeployed) != taskNum) {
×
2687
        for (int32_t i = 0; i < taskNum; ++i) {
×
2688
          SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, i);
×
2689
          if (pExt->deploy.task.streamId == streamId && !pExt->deployed) {
×
2690
            pExt->deployed = true;
×
2691
          }
2692
        }
2693
      }
2694

2695
      taskNum = taosArrayGetSize(pSnode->runnerList);
×
2696
      if (atomic_load_32(&pSnode->runnerDeployed) != taskNum) {
×
2697
        for (int32_t i = 0; i < taskNum; ++i) {
×
2698
          SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, i);
×
2699
          if (pExt->deploy.task.streamId == streamId && !pExt->deployed) {
×
2700
            pExt->deployed = true;
×
2701
          }
2702
        }
2703
      }
2704
    }
2705
  }
2706

2707
  return TSDB_CODE_SUCCESS;
×
2708
}
2709

2710
static int32_t msmRemoveStreamFromMaps(SMnode* pMnode, int64_t streamId) {
444✔
2711
  int32_t code = TSDB_CODE_SUCCESS;
444✔
2712
  int32_t lino = 0;
444✔
2713

2714
  mstsInfo("start to remove stream from maps, current stream num:%d", taosHashGetSize(mStreamMgmt.streamMap));
444✔
2715

2716
  TAOS_CHECK_EXIT(msmSTRemoveStream(streamId, true));
444✔
2717

2718
_exit:
444✔
2719

2720
  if (code) {
444✔
2721
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2722
  } else {
2723
    mstsInfo("end remove stream from maps, current stream num:%d", taosHashGetSize(mStreamMgmt.streamMap));
444✔
2724
  }
2725

2726
  return code;
444✔
2727
}
2728

2729
void msmUndeployStream(SMnode* pMnode, int64_t streamId, char* streamName) {
37,124✔
2730
  int32_t code = TSDB_CODE_SUCCESS;
37,124✔
2731
  int32_t lino = 0;
37,124✔
2732

2733
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
37,124✔
2734
  if (0 == active || MND_STM_STATE_NORMAL != state) {
37,124✔
2735
    mstsError("stream mgmt not available since active:%d state:%d", active, state);
328✔
2736
    return;
328✔
2737
  }
2738

2739
  SStmStatus* pStream = (SStmStatus*)taosHashAcquire(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
36,796✔
2740
  if (NULL == pStream) {
36,796✔
2741
    mstsInfo("stream %s already not in streamMap", streamName);
1,902✔
2742
    goto _exit;
1,902✔
2743
  }
2744

2745
  atomic_store_8(&pStream->stopped, 2);
34,894✔
2746

2747
  mstsInfo("set stream %s stopped by user", streamName);
34,894✔
2748

2749
_exit:
×
2750

2751
  taosHashRelease(mStreamMgmt.streamMap, pStream);
36,796✔
2752

2753
  if (code) {
36,796✔
2754
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2755
  }
2756

2757
  return;
36,796✔
2758
}
2759

2760
int32_t msmRecalcStream(SMnode* pMnode, int64_t streamId, STimeWindow* timeRange) {
3,488✔
2761
  int32_t code = TSDB_CODE_SUCCESS;
3,488✔
2762
  int32_t lino = 0;
3,488✔
2763

2764
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
3,488✔
2765
  if (0 == active || MND_STM_STATE_NORMAL != state) {
3,488✔
2766
    mstsError("stream mgmt not available since active:%d state:%d", active, state);
×
2767
    return TSDB_CODE_MND_STREAM_NOT_AVAILABLE;
×
2768
  }
2769

2770
  SStmStatus* pStream = (SStmStatus*)taosHashAcquire(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
3,488✔
2771
  if (NULL == pStream || !STREAM_IS_RUNNING(pStream)) {
3,488✔
2772
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
2773
    mstsInfo("stream still not in streamMap, streamRemains:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
2774
    goto _exit;
×
2775
  }
2776

2777
  TAOS_CHECK_EXIT(mstAppendNewRecalcRange(streamId, pStream, timeRange));
3,488✔
2778

2779
_exit:
3,488✔
2780

2781
  taosHashRelease(mStreamMgmt.streamMap, pStream);
3,488✔
2782

2783
  if (code) {
3,488✔
2784
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2785
  }
2786

2787
  return code;
3,488✔
2788
}
2789

2790
static void msmHandleStreamActions(SStmGrpCtx* pCtx) {
54,860✔
2791
  int32_t code = TSDB_CODE_SUCCESS;
54,860✔
2792
  int32_t lino = 0;
54,860✔
2793
  SStmQNode* pQNode = NULL;
54,860✔
2794

2795
  while (mndStreamActionDequeue(mStreamMgmt.actionQ, &pQNode)) {
265,321✔
2796
    switch (pQNode->type) {
210,461✔
2797
      case STREAM_ACT_DEPLOY:
210,461✔
2798
        if (pQNode->streamAct) {
210,461✔
2799
          mstDebug("start to handle stream deploy action");
208,741✔
2800
          TAOS_CHECK_EXIT(msmLaunchStreamDeployAction(pCtx, &pQNode->action.stream));
208,741✔
2801
        } else {
2802
          mstDebug("start to handle task deploy action");
1,720✔
2803
          TAOS_CHECK_EXIT(msmLaunchTaskDeployAction(pCtx, &pQNode->action.task));
1,720✔
2804
        }
2805
        break;
210,461✔
2806
      default:
×
2807
        break;
×
2808
    }
2809
  }
2810

2811
_exit:
54,860✔
2812

2813
  if (code) {
54,860✔
UNCOV
2814
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2815
  }
2816
}
54,860✔
2817

2818
void msmStopAllStreamsByGrant(int32_t errCode) {
×
2819
  SStmStatus* pStatus = NULL;
×
2820
  void* pIter = NULL;
×
2821
  int64_t streamId = 0;
×
2822
  
2823
  while (true) {
2824
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
×
2825
    if (NULL == pIter) {
×
2826
      break;
×
2827
    }
2828

2829
    pStatus = (SStmStatus*)pIter;
×
2830

2831
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
2832
    atomic_store_8(&pStatus->stopped, 4);
×
2833

2834
    mstsInfo("set stream stopped since %s", tstrerror(errCode));
×
2835
  }
2836
}
×
2837

2838
int32_t msmHandleGrantExpired(SMnode *pMnode, int32_t errCode) {
×
2839
  mstInfo("stream grant expired");
×
2840

2841
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
×
2842
    mstWarn("mnode stream is NOT active, ignore handling");
×
2843
    return errCode;
×
2844
  }
2845

2846
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, true);
×
2847

2848
  msmStopAllStreamsByGrant(errCode);
×
2849

2850
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
×
2851
  
2852
  return errCode;
×
2853
}
2854

2855
static int32_t msmInitStreamDeploy(SStmStreamDeploy* pStream, SStmTaskDeploy* pDeploy) {
1,613,062✔
2856
  int32_t code = TSDB_CODE_SUCCESS;
1,613,062✔
2857
  int32_t lino = 0;
1,613,062✔
2858
  int64_t streamId = pDeploy->task.streamId;
1,613,062✔
2859
  
2860
  switch (pDeploy->task.type) {
1,613,062✔
2861
    case STREAM_READER_TASK:
694,714✔
2862
      if (NULL == pStream->readerTasks) {
694,714✔
2863
        pStream->streamId = streamId;
265,344✔
2864
        pStream->readerTasks = taosArrayInit(20, sizeof(SStmTaskDeploy));
265,344✔
2865
        TSDB_CHECK_NULL(pStream->readerTasks, code, lino, _exit, terrno);
265,344✔
2866
      }
2867
      
2868
      TSDB_CHECK_NULL(taosArrayPush(pStream->readerTasks, pDeploy), code, lino, _exit, terrno);
1,389,428✔
2869
      break;
694,714✔
2870
    case STREAM_TRIGGER_TASK:
205,044✔
2871
      pStream->streamId = streamId;
205,044✔
2872
      pStream->triggerTask = taosMemoryMalloc(sizeof(SStmTaskDeploy));
205,044✔
2873
      TSDB_CHECK_NULL(pStream->triggerTask, code, lino, _exit, terrno);
205,044✔
2874
      memcpy(pStream->triggerTask, pDeploy, sizeof(SStmTaskDeploy));
205,044✔
2875
      break;
205,044✔
2876
    case STREAM_RUNNER_TASK:
713,304✔
2877
      if (NULL == pStream->runnerTasks) {
713,304✔
2878
        pStream->streamId = streamId;
208,465✔
2879
        pStream->runnerTasks = taosArrayInit(20, sizeof(SStmTaskDeploy));
208,465✔
2880
        TSDB_CHECK_NULL(pStream->runnerTasks, code, lino, _exit, terrno);
208,465✔
2881
      }      
2882
      TSDB_CHECK_NULL(taosArrayPush(pStream->runnerTasks, pDeploy), code, lino, _exit, terrno);
1,426,608✔
2883
      break;
713,304✔
2884
    default:
×
2885
      break;
×
2886
  }
2887

2888
_exit:
1,613,062✔
2889

2890
  if (code) {
1,613,062✔
2891
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2892
  }
2893

2894
  return code;
1,613,062✔
2895
}
2896

2897
static int32_t msmGrpAddDeployTask(SHashObj* pHash, SStmTaskDeploy* pDeploy) {
1,613,062✔
2898
  int32_t code = TSDB_CODE_SUCCESS;
1,613,062✔
2899
  int32_t lino = 0;
1,613,062✔
2900
  int64_t streamId = pDeploy->task.streamId;
1,613,062✔
2901
  SStreamTask* pTask = &pDeploy->task;
1,613,062✔
2902
  SStmStreamDeploy streamDeploy = {0};
1,613,062✔
2903
  SStmStreamDeploy* pStream = NULL;
1,613,062✔
2904
   
2905
  while (true) {
2906
    pStream = taosHashAcquire(pHash, &streamId, sizeof(streamId));
1,613,062✔
2907
    if (NULL == pStream) {
1,613,062✔
2908
      TAOS_CHECK_EXIT(msmInitStreamDeploy(&streamDeploy, pDeploy));
276,721✔
2909
      code = taosHashPut(pHash, &streamId, sizeof(streamId), &streamDeploy, sizeof(streamDeploy));
276,721✔
2910
      if (TSDB_CODE_SUCCESS == code) {
276,721✔
2911
        goto _exit;
276,721✔
2912
      }
2913

2914
      if (TSDB_CODE_DUP_KEY != code) {
×
2915
        goto _exit;
×
2916
      }    
2917

2918
      tFreeSStmStreamDeploy(&streamDeploy);
×
2919
      continue;
×
2920
    }
2921

2922
    TAOS_CHECK_EXIT(msmInitStreamDeploy(pStream, pDeploy));
1,336,341✔
2923
    
2924
    break;
1,336,341✔
2925
  }
2926
  
2927
_exit:
1,613,062✔
2928

2929
  taosHashRelease(pHash, pStream);
1,613,062✔
2930

2931
  if (code) {
1,613,062✔
2932
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2933
  } else {
2934
    msttDebug("task added to GRP deployMap, taskIdx:%d", pTask->taskIdx);
1,613,062✔
2935
  }
2936

2937
  return code;
1,613,062✔
2938
}
2939

2940

2941
int32_t msmGrpAddDeployTasks(SHashObj* pHash, SArray* pTasks, int32_t* deployed) {
283,067✔
2942
  int32_t code = TSDB_CODE_SUCCESS;
283,067✔
2943
  int32_t lino = 0;
283,067✔
2944
  int32_t taskNum = taosArrayGetSize(pTasks);
283,067✔
2945

2946
  for (int32_t i = 0; i < taskNum; ++i) {
1,897,641✔
2947
    SStmTaskToDeployExt* pExt = taosArrayGet(pTasks, i);
1,614,574✔
2948
    if (pExt->deployed) {
1,614,574✔
2949
      continue;
1,512✔
2950
    }
2951

2952
    TAOS_CHECK_EXIT(msmGrpAddDeployTask(pHash, &pExt->deploy));
1,613,062✔
2953
    pExt->deployed = true;
1,613,062✔
2954

2955
    (void)atomic_add_fetch_32(deployed, 1);
1,613,062✔
2956
  }
2957

2958
_exit:
283,067✔
2959

2960
  if (code) {
283,067✔
2961
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2962
  }
2963

2964
  return code;
283,067✔
2965
}
2966

2967
int32_t msmGrpAddDeployVgTasks(SStmGrpCtx* pCtx) {
79,346✔
2968
  int32_t code = TSDB_CODE_SUCCESS;
79,346✔
2969
  int32_t lino = 0;
79,346✔
2970
  int32_t vgNum = taosArrayGetSize(pCtx->pReq->pVgLeaders);
79,346✔
2971
  SStmVgTasksToDeploy* pVg = NULL;
79,346✔
2972
  //int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pCtx->pReq->streamGId);
2973

2974
  mstDebug("start to add stream vgroup tasks deploy");
79,346✔
2975
  
2976
  for (int32_t i = 0; i < vgNum; ++i) {
499,011✔
2977
    int32_t* vgId = taosArrayGet(pCtx->pReq->pVgLeaders, i);
419,665✔
2978

2979
    msmUpdateVgroupUpTs(pCtx, *vgId);
419,665✔
2980

2981
    pVg = taosHashAcquire(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId));
419,665✔
2982
    if (NULL == pVg) {
419,665✔
2983
      continue;
248,260✔
2984
    }
2985

2986
    if (taosRTryLockLatch(&pVg->lock)) {
171,405✔
2987
      continue;
×
2988
    }
2989
    
2990
    if (atomic_load_32(&pVg->deployed) == taosArrayGetSize(pVg->taskList)) {
171,405✔
2991
      taosRUnLockLatch(&pVg->lock);
×
2992
      continue;
×
2993
    }
2994
    
2995
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pVg->taskList, &pVg->deployed));
171,405✔
2996
    taosRUnLockLatch(&pVg->lock);
171,405✔
2997
  }
2998

2999
_exit:
79,346✔
3000

3001
  if (code) {
79,346✔
3002
    if (pVg) {
×
3003
      taosRUnLockLatch(&pVg->lock);
×
3004
    }
3005

3006
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3007
  }
3008

3009
  return code;
79,346✔
3010
}
3011

3012
int32_t msmGrpAddDeploySnodeTasks(SStmGrpCtx* pCtx) {
119,766✔
3013
  int32_t code = TSDB_CODE_SUCCESS;
119,766✔
3014
  int32_t lino = 0;
119,766✔
3015
  SStmSnodeTasksDeploy* pSnode = NULL;
119,766✔
3016
  SStreamHbMsg* pReq = pCtx->pReq;
119,766✔
3017

3018
  mstDebug("start to add stream snode tasks deploy");
119,766✔
3019
  
3020
  pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &pReq->snodeId, sizeof(pReq->snodeId));
119,766✔
3021
  if (NULL == pSnode) {
119,766✔
3022
    return TSDB_CODE_SUCCESS;
62,306✔
3023
  }
3024

3025
  (void)mstWaitLock(&pSnode->lock, false);
57,460✔
3026
  
3027
  if (atomic_load_32(&pSnode->triggerDeployed) < taosArrayGetSize(pSnode->triggerList)) {
57,460✔
3028
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pSnode->triggerList, &pSnode->triggerDeployed));
54,202✔
3029
  }
3030

3031
  if (atomic_load_32(&pSnode->runnerDeployed) < taosArrayGetSize(pSnode->runnerList)) {
57,460✔
3032
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pSnode->runnerList, &pSnode->runnerDeployed));
57,460✔
3033
  }
3034
  
3035
  taosWUnLockLatch(&pSnode->lock);
57,460✔
3036

3037
_exit:
57,460✔
3038

3039
  if (code) {
57,460✔
3040
    if (pSnode) {
×
3041
      taosWUnLockLatch(&pSnode->lock);
×
3042
    }
3043

3044
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3045
  }
3046

3047
  return code;
57,460✔
3048
}
3049

3050
int32_t msmUpdateStreamLastActTs(int64_t streamId, int64_t currTs) {
734,364✔
3051
  int32_t code = TSDB_CODE_SUCCESS;
734,364✔
3052
  int32_t lino = 0;
734,364✔
3053
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
734,364✔
3054
  if (NULL == pStatus) {
734,364✔
3055
    mstsWarn("stream already not exists in streamMap, mapSize:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
3056
    return TSDB_CODE_SUCCESS;
×
3057
  }
3058
  
3059
  pStatus->lastActionTs = currTs;
734,364✔
3060

3061
_exit:
734,364✔
3062

3063
  if (code) {
734,364✔
3064
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3065
  }
3066

3067
  return code;
734,364✔
3068
}
3069

3070
int32_t msmRspAddStreamsDeploy(SStmGrpCtx* pCtx) {
78,457✔
3071
  int32_t code = TSDB_CODE_SUCCESS;
78,457✔
3072
  int32_t lino = 0;
78,457✔
3073
  int32_t streamNum = taosHashGetSize(pCtx->deployStm);
78,457✔
3074
  void* pIter = NULL;
78,457✔
3075

3076
  mstDebug("start to add group %d deploy streams, streamNum:%d", pCtx->pReq->streamGId, taosHashGetSize(pCtx->deployStm));
78,457✔
3077
  
3078
  pCtx->pRsp->deploy.streamList = taosArrayInit(streamNum, sizeof(SStmStreamDeploy));
78,457✔
3079
  TSDB_CHECK_NULL(pCtx->pRsp->deploy.streamList, code, lino, _exit, terrno);
78,457✔
3080

3081
  while (1) {
276,721✔
3082
    pIter = taosHashIterate(pCtx->deployStm, pIter);
355,178✔
3083
    if (pIter == NULL) {
355,178✔
3084
      break;
78,457✔
3085
    }
3086
    
3087
    SStmStreamDeploy *pDeploy = (SStmStreamDeploy *)pIter;
276,721✔
3088
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->deploy.streamList, pDeploy), code, lino, _exit, terrno);
553,442✔
3089

3090
    int64_t streamId = pDeploy->streamId;
276,721✔
3091
    mstsDebug("stream DEPLOY added to dnode %d hb rsp, readerTasks:%zu, triggerTask:%d, runnerTasks:%zu", 
276,721✔
3092
        pCtx->pReq->dnodeId, taosArrayGetSize(pDeploy->readerTasks), pDeploy->triggerTask ? 1 : 0, taosArrayGetSize(pDeploy->runnerTasks));
3093

3094
    mstClearSStmStreamDeploy(pDeploy);
276,721✔
3095
    
3096
    TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(pDeploy->streamId, pCtx->currTs));
276,721✔
3097
  }
3098
  
3099
_exit:
78,457✔
3100

3101
  if (pIter) {
78,457✔
3102
    taosHashCancelIterate(pCtx->deployStm, pIter);
×
3103
  }
3104

3105
  if (code) {
78,457✔
3106
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3107
  }
3108
  
3109
  return code;
78,457✔
3110
}
3111

3112
void msmCleanDeployedVgTasks(SArray* pVgLeaders) {
79,346✔
3113
  int32_t code = TSDB_CODE_SUCCESS;
79,346✔
3114
  int32_t lino = 0;
79,346✔
3115
  int32_t vgNum = taosArrayGetSize(pVgLeaders);
79,346✔
3116
  SStmVgTasksToDeploy* pVg = NULL;
79,346✔
3117
  
3118
  for (int32_t i = 0; i < vgNum; ++i) {
499,011✔
3119
    int32_t* vgId = taosArrayGet(pVgLeaders, i);
419,665✔
3120
    pVg = taosHashAcquire(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId));
419,665✔
3121
    if (NULL == pVg) {
419,665✔
3122
      continue;
248,260✔
3123
    }
3124

3125
    if (taosWTryLockLatch(&pVg->lock)) {
171,405✔
UNCOV
3126
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
×
UNCOV
3127
      continue;
×
3128
    }
3129
    
3130
    if (atomic_load_32(&pVg->deployed) <= 0) {
171,405✔
3131
      taosWUnLockLatch(&pVg->lock);
×
3132
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
×
3133
      continue;
×
3134
    }
3135

3136
    int32_t taskNum = taosArrayGetSize(pVg->taskList);
171,405✔
3137
    if (atomic_load_32(&pVg->deployed) == taskNum) {
171,405✔
3138
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeployVgTaskNum, taskNum);
171,153✔
3139
      taosArrayDestroyEx(pVg->taskList, mstDestroySStmTaskToDeployExt);
171,153✔
3140
      pVg->taskList = NULL;
171,153✔
3141
      TAOS_UNUSED(taosHashRemove(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId)));
171,153✔
3142
      taosWUnLockLatch(&pVg->lock);
171,153✔
3143
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
171,153✔
3144
      continue;
171,153✔
3145
    }
3146

3147
    for (int32_t m = taskNum - 1; m >= 0; --m) {
1,260✔
3148
      SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, m);
1,008✔
3149
      if (!pExt->deployed) {
1,008✔
3150
        continue;
×
3151
      }
3152

3153
      mstDestroySStmTaskToDeployExt(pExt);
1,008✔
3154

3155
      taosArrayRemove(pVg->taskList, m);
1,008✔
3156
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeployVgTaskNum, 1);
1,008✔
3157
    }
3158
    atomic_store_32(&pVg->deployed, 0);
252✔
3159
    taosWUnLockLatch(&pVg->lock);
252✔
3160
    taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
252✔
3161
  }
3162

3163
_exit:
79,346✔
3164

3165
  if (code) {
79,346✔
3166
    if (pVg) {
×
3167
      taosWUnLockLatch(&pVg->lock);
×
3168
    }
3169

3170
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3171
  }
3172
}
79,346✔
3173

3174
void msmCleanDeployedSnodeTasks (int32_t snodeId) {
138,339✔
3175
  if (!GOT_SNODE(snodeId)) {
138,339✔
3176
    return;
18,573✔
3177
  }
3178
  
3179
  int32_t code = TSDB_CODE_SUCCESS;
119,766✔
3180
  SStmSnodeTasksDeploy* pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &snodeId, sizeof(snodeId));
119,766✔
3181
  if (NULL == pSnode) {
119,766✔
3182
    return;
62,306✔
3183
  }
3184

3185
  if (taosWTryLockLatch(&pSnode->lock)) {
57,460✔
3186
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
×
3187
    return;
×
3188
  }
3189

3190
  int32_t triggerNum = taosArrayGetSize(pSnode->triggerList);
57,460✔
3191
  int32_t runnerNum = taosArrayGetSize(pSnode->runnerList);
57,460✔
3192
  
3193
  if (atomic_load_32(&pSnode->triggerDeployed) <= 0 && atomic_load_32(&pSnode->runnerDeployed) <= 0) {
57,460✔
3194
    taosWUnLockLatch(&pSnode->lock);
×
3195
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
×
3196
    return;
×
3197
  }
3198

3199
  if (atomic_load_32(&pSnode->triggerDeployed) == triggerNum) {
57,460✔
3200
    (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, triggerNum);
57,208✔
3201
    taosArrayDestroyEx(pSnode->triggerList, mstDestroySStmTaskToDeployExt);
57,208✔
3202
    pSnode->triggerList = NULL;
57,208✔
3203
  }
3204

3205
  if (atomic_load_32(&pSnode->runnerDeployed) == runnerNum) {
57,460✔
3206
    (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, runnerNum);
57,208✔
3207
    taosArrayDestroyEx(pSnode->runnerList, mstDestroySStmTaskToDeployExt);
57,208✔
3208
    pSnode->runnerList = NULL;
57,208✔
3209
  }
3210

3211
  if (NULL == pSnode->triggerList && NULL == pSnode->runnerList) {
57,460✔
3212
    TAOS_UNUSED(taosHashRemove(mStreamMgmt.toDeploySnodeMap, &snodeId, sizeof(snodeId)));
57,208✔
3213
    taosWUnLockLatch(&pSnode->lock);
57,208✔
3214
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
57,208✔
3215
    return;
57,208✔
3216
  }
3217

3218
  if (atomic_load_32(&pSnode->triggerDeployed) > 0 && pSnode->triggerList) {
252✔
3219
    for (int32_t m = triggerNum - 1; m >= 0; --m) {
756✔
3220
      SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, m);
504✔
3221
      if (!pExt->deployed) {
504✔
3222
        continue;
×
3223
      }
3224

3225
      mstDestroySStmTaskToDeployExt(pExt);
504✔
3226
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
504✔
3227
      taosArrayRemove(pSnode->triggerList, m);
504✔
3228
    }
3229
    
3230
    pSnode->triggerDeployed = 0;
252✔
3231
  }
3232

3233
  if (atomic_load_32(&pSnode->runnerDeployed) > 0 && pSnode->runnerList) {
252✔
3234
    for (int32_t m = runnerNum - 1; m >= 0; --m) {
1,764✔
3235
      SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, m);
1,512✔
3236
      if (!pExt->deployed) {
1,512✔
3237
        continue;
×
3238
      }
3239

3240
      mstDestroySStmTaskToDeployExt(pExt);
1,512✔
3241
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
1,512✔
3242
      taosArrayRemove(pSnode->runnerList, m);
1,512✔
3243
    }
3244
    
3245
    pSnode->runnerDeployed = 0;
252✔
3246
  }
3247
  
3248
  taosWUnLockLatch(&pSnode->lock);
252✔
3249
  taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
252✔
3250
}
3251

3252
void msmClearStreamToDeployMaps(SStreamHbMsg* pHb) {
17,761,871✔
3253
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
17,761,871✔
3254
    msmCleanDeployedVgTasks(pHb->pVgLeaders);
79,346✔
3255
  }
3256

3257
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0) {
17,761,871✔
3258
    msmCleanDeployedSnodeTasks(pHb->snodeId);
138,339✔
3259
  }
3260
}
17,761,871✔
3261

3262
void msmCleanStreamGrpCtx(SStreamHbMsg* pHb) {
17,761,871✔
3263
  int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pHb->streamGId);
17,761,871✔
3264
  if (mStreamMgmt.tCtx) {
17,761,871✔
3265
    taosHashClear(mStreamMgmt.tCtx[tidx].actionStm[pHb->streamGId]);
17,687,156✔
3266
    taosHashClear(mStreamMgmt.tCtx[tidx].deployStm[pHb->streamGId]);
17,687,156✔
3267
  }
3268
}
17,761,871✔
3269

3270
int32_t msmGrpAddActionStart(SHashObj* pHash, int64_t streamId, SStmTaskId* pId) {
200,562✔
3271
  int32_t code = TSDB_CODE_SUCCESS;
200,562✔
3272
  int32_t lino = 0;
200,562✔
3273
  int32_t action = STREAM_ACT_START;
200,562✔
3274
  SStmAction *pAction = taosHashGet(pHash, &streamId, sizeof(streamId));
200,562✔
3275
  if (pAction) {
200,562✔
3276
    pAction->actions |= action;
×
3277
    pAction->start.triggerId = *pId;
×
3278
    mstsDebug("stream append START action, actions:%x", pAction->actions);
×
3279
  } else {
3280
    SStmAction newAction = {0};
200,562✔
3281
    newAction.actions = action;
200,562✔
3282
    newAction.start.triggerId = *pId;
200,562✔
3283
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
200,562✔
3284
    mstsDebug("stream add START action, actions:%x", newAction.actions);
200,562✔
3285
  }
3286

3287
_exit:
200,562✔
3288

3289
  if (code) {
200,562✔
3290
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3291
  }
3292

3293
  return code;
200,562✔
3294
}
3295

3296
int32_t msmGrpAddActionUpdateTrigger(SHashObj* pHash, int64_t streamId) {
×
3297
  int32_t code = TSDB_CODE_SUCCESS;
×
3298
  int32_t lino = 0;
×
3299
  int32_t action = STREAM_ACT_UPDATE_TRIGGER;
×
3300
  
3301
  SStmAction *pAction = taosHashGet(pHash, &streamId, sizeof(streamId));
×
3302
  if (pAction) {
×
3303
    pAction->actions |= action;
×
3304
    mstsDebug("stream append UPDATE_TRIGGER action, actions:%x", pAction->actions);
×
3305
  } else {
3306
    SStmAction newAction = {0};
×
3307
    newAction.actions = action;
×
3308
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
×
3309
    mstsDebug("stream add UPDATE_TRIGGER action, actions:%x", newAction.actions);
×
3310
  }
3311

3312
_exit:
×
3313

3314
  if (code) {
×
3315
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3316
  }
3317

3318
  return code;
×
3319
}
3320

3321

3322

3323
int32_t msmGrpAddActionUndeploy(SStmGrpCtx* pCtx, int64_t streamId, SStreamTask* pTask) {
257,081✔
3324
  int32_t code = TSDB_CODE_SUCCESS;
257,081✔
3325
  int32_t lino = 0;
257,081✔
3326
  int32_t action = STREAM_ACT_UNDEPLOY;
257,081✔
3327
  bool    dropped = false;
257,081✔
3328

3329
  TAOS_CHECK_EXIT(mstIsStreamDropped(pCtx->pMnode, streamId, &dropped));
257,081✔
3330
  mstsDebug("stream dropped: %d", dropped);
257,081✔
3331
  
3332
  SStmAction *pAction = taosHashGet(pCtx->actionStm, &streamId, sizeof(streamId));
257,081✔
3333
  if (pAction) {
257,081✔
3334
    pAction->actions |= action;
207,189✔
3335
    if (NULL == pAction->undeploy.taskList) {
207,189✔
3336
      pAction->undeploy.taskList = taosArrayInit(pCtx->taskNum, POINTER_BYTES);
×
3337
      TSDB_CHECK_NULL(pAction->undeploy.taskList, code, lino, _exit, terrno);
×
3338
    }
3339

3340
    TSDB_CHECK_NULL(taosArrayPush(pAction->undeploy.taskList, &pTask), code, lino, _exit, terrno);
414,378✔
3341
    if (pAction->undeploy.doCheckpoint) {
207,189✔
3342
      pAction->undeploy.doCheckpoint = dropped ? false : true;
33,124✔
3343
    }
3344
    if (!pAction->undeploy.doCleanup) {
207,189✔
3345
      pAction->undeploy.doCleanup = dropped ? true : false;
33,124✔
3346
    }
3347
    
3348
    msttDebug("task append UNDEPLOY action[%d,%d], actions:%x", pAction->undeploy.doCheckpoint, pAction->undeploy.doCleanup, pAction->actions);
207,189✔
3349
  } else {
3350
    SStmAction newAction = {0};
49,892✔
3351
    newAction.actions = action;
49,892✔
3352
    newAction.undeploy.doCheckpoint = dropped ? false : true;
49,892✔
3353
    newAction.undeploy.doCleanup = dropped ? true : false;
49,892✔
3354
    newAction.undeploy.taskList = taosArrayInit(pCtx->taskNum, POINTER_BYTES);
49,892✔
3355
    TSDB_CHECK_NULL(newAction.undeploy.taskList, code, lino, _exit, terrno);
49,892✔
3356
    TSDB_CHECK_NULL(taosArrayPush(newAction.undeploy.taskList, &pTask), code, lino, _exit, terrno);
99,784✔
3357
    TAOS_CHECK_EXIT(taosHashPut(pCtx->actionStm, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
49,892✔
3358
    
3359
    msttDebug("task add UNDEPLOY action[%d,%d]", newAction.undeploy.doCheckpoint, newAction.undeploy.doCleanup);
49,892✔
3360
  }
3361

3362
_exit:
257,081✔
3363

3364
  if (code) {
257,081✔
3365
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3366
  }
3367

3368
  return code;
257,081✔
3369
}
3370

3371
int32_t msmGrpAddActionRecalc(SStmGrpCtx* pCtx, int64_t streamId, SArray* recalcList) {
3,488✔
3372
  int32_t code = TSDB_CODE_SUCCESS;
3,488✔
3373
  int32_t lino = 0;
3,488✔
3374
  int32_t action = STREAM_ACT_RECALC;
3,488✔
3375
  SStmAction newAction = {0};
3,488✔
3376
  
3377
  SStmAction *pAction = taosHashGet(pCtx->actionStm, &streamId, sizeof(streamId));
3,488✔
3378
  if (pAction) {
3,488✔
3379
    pAction->actions |= action;
×
3380
    pAction->recalc.recalcList = recalcList;
×
3381

3382
    mstsDebug("stream append recalc action, listSize:%d, actions:%x", (int32_t)taosArrayGetSize(recalcList), pAction->actions);
×
3383
  } else {
3384
    newAction.actions = action;
3,488✔
3385
    newAction.recalc.recalcList = recalcList;
3,488✔
3386
    
3387
    TAOS_CHECK_EXIT(taosHashPut(pCtx->actionStm, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
3,488✔
3388
    
3389
    mstsDebug("stream add recalc action, listSize:%d", (int32_t)taosArrayGetSize(recalcList));
3,488✔
3390
  }
3391

3392
_exit:
3,488✔
3393

3394
  if (code) {
3,488✔
3395
    mstDestroySStmAction(&newAction);
×
3396
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3397
  }
3398

3399
  return code;
3,488✔
3400
}
3401

3402
bool msmCheckStreamStartCond(int64_t streamId, int32_t snodeId) {
288,115✔
3403
  SStmStatus* pStream = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
288,115✔
3404
  if (NULL == pStream) {
288,115✔
3405
    return false;
×
3406
  }
3407

3408
  if (pStream->triggerTask->id.nodeId != snodeId || STREAM_STATUS_INIT != pStream->triggerTask->status) {
288,115✔
3409
    return false;
×
3410
  }
3411

3412
  int32_t readerNum = taosArrayGetSize(pStream->trigReaders);
288,115✔
3413
  for (int32_t i = 0; i < readerNum; ++i) {
635,927✔
3414
    SStmTaskStatus* pStatus = taosArrayGet(pStream->trigReaders, i);
347,812✔
3415
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
347,812✔
3416
      return false;
×
3417
    }
3418
  }
3419

3420
  readerNum = msmGetTrigOReaderSize(pStream->trigOReaders);
288,115✔
3421
  for (int32_t i = 0; i < readerNum; ++i) {
288,115✔
3422
    SStmTaskStatus* pStatus = msmGetTrigOReader(pStream->trigOReaders, i);
×
3423
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
×
3424
      return false;
×
3425
    }
3426
  }
3427

3428
  readerNum = MST_LIST_SIZE(pStream->calcReaders);
288,115✔
3429
  SListNode* pNode = listHead(pStream->calcReaders);
288,115✔
3430
  for (int32_t i = 0; i < readerNum; ++i) {
880,506✔
3431
    SStmTaskStatus* pStatus = (SStmTaskStatus*)pNode->data;
592,391✔
3432
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
592,391✔
3433
      return false;
×
3434
    }
3435
    pNode = TD_DLIST_NODE_NEXT(pNode);
592,391✔
3436
  }
3437

3438
  for (int32_t i = 0; i < pStream->runnerDeploys; ++i) {
884,968✔
3439
    int32_t runnerNum = taosArrayGetSize(pStream->runners[i]);
684,406✔
3440
    for (int32_t m = 0; m < runnerNum; ++m) {
1,386,832✔
3441
      SStmTaskStatus* pStatus = taosArrayGet(pStream->runners[i], m);
789,979✔
3442
      if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
789,979✔
3443
        return false;
87,553✔
3444
      }
3445
    }
3446
  }
3447
  
3448
  return true;
200,562✔
3449
}
3450

3451

3452
void msmHandleTaskAbnormalStatus(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pMsg, SStmTaskStatus* pTaskStatus) {
14,744,595✔
3453
  int32_t code = TSDB_CODE_SUCCESS;
14,744,595✔
3454
  int32_t lino = 0;
14,744,595✔
3455
  int32_t action = 0;
14,744,595✔
3456
  int64_t streamId = pMsg->streamId;
14,744,595✔
3457
  SStreamTask* pTask = (SStreamTask*)pMsg;
14,744,595✔
3458
  int8_t  stopped = 0;
14,744,595✔
3459

3460
  msttDebug("start to handle task abnormal status %d", pTask->status);
14,744,595✔
3461
  
3462
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
14,744,595✔
3463
  if (NULL == pStatus) {
14,744,595✔
3464
    msttInfo("stream no longer exists in streamMap, try to undeploy current task, idx:%d", pMsg->taskIdx);
×
3465
    TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
×
3466
    return;
14,071✔
3467
  }
3468

3469
  stopped = atomic_load_8(&pStatus->stopped);
14,744,595✔
3470
  if (stopped) {
14,744,595✔
3471
    msttInfo("stream stopped %d, try to undeploy current task, idx:%d", stopped, pMsg->taskIdx);
×
3472
    TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
×
3473
    return;
×
3474
  }
3475
  
3476
  switch (pMsg->status) {
14,744,595✔
3477
    case STREAM_STATUS_INIT:      
14,737,700✔
3478
      if (STREAM_TRIGGER_TASK != pMsg->type) {
14,737,700✔
3479
        msttTrace("task status is INIT and not trigger task, ignore it, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
14,332,956✔
3480
        return;
14,332,956✔
3481
      }
3482
      
3483
      if (INT64_MIN == pStatus->lastActionTs) {
404,744✔
3484
        msttDebug("task still not deployed, ignore it, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
×
3485
        return;
×
3486
      }
3487
      
3488
      if ((pCtx->currTs - pStatus->lastActionTs) < STREAM_ACT_MIN_DELAY_MSEC) {
404,744✔
3489
        msttDebug("task wait not enough between actions, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
116,629✔
3490
        return;
116,629✔
3491
      }
3492

3493
      if (STREAM_IS_RUNNING(pStatus)) {
288,115✔
3494
        msttDebug("stream already running, ignore status: %s", gStreamStatusStr[pTask->status]);
×
3495
      } else if (GOT_SNODE(pCtx->pReq->snodeId) && msmCheckStreamStartCond(streamId, pCtx->pReq->snodeId)) {
288,115✔
3496
        TAOS_CHECK_EXIT(msmGrpAddActionStart(pCtx->actionStm, streamId, &pStatus->triggerTask->id));
200,562✔
3497
      }
3498
      break;
288,115✔
3499
    case STREAM_STATUS_FAILED:
6,895✔
3500
      //STREAMTODO ADD ERRCODE HANDLE
3501
      if (STREAM_RUNNER_TASK == pTask->type || STREAM_TRIGGER_TASK == pTask->type) {
6,895✔
3502
        msttWarn("task failed with error:%s, try to undeploy whole stream, idx:%d", tstrerror(pMsg->errorCode),
6,687✔
3503
                 pMsg->taskIdx);
3504
        msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
6,687✔
3505
      } else {
3506
        msttInfo("task failed with error:%s, try to undeploy current task, idx:%d", tstrerror(pMsg->errorCode),
208✔
3507
                 pMsg->taskIdx);
3508
        TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
208✔
3509
      }
3510
      break;
6,895✔
3511
    default:
×
3512
      break;
×
3513
  }
3514

3515
_exit:
295,010✔
3516

3517
  if (code) {
295,010✔
3518
    msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
3519
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3520
  }
3521
}
3522

3523
void msmHandleStreamTaskErr(SStmGrpCtx* pCtx, EStmErrType err, SStmTaskStatusMsg* pStatus) {
256,873✔
3524
  int32_t code = TSDB_CODE_SUCCESS;
256,873✔
3525
  int32_t lino = 0;
256,873✔
3526
  SStreamTask* pTask = (SStreamTask*)pStatus;
256,873✔
3527
  int64_t streamId = pStatus->streamId;
256,873✔
3528

3529
  msttInfo("start to handle task error, type: %d", err);
256,873✔
3530

3531
  TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
256,873✔
3532

3533
_exit:
256,873✔
3534

3535
  if (code) {
256,873✔
3536
    // IGNORE STOP STREAM BY ERROR  
3537
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3538
  }
3539
}
256,873✔
3540

3541
void msmChkHandleTriggerOperations(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask, SStmTaskStatus* pStatus) {
5,868,337✔
3542
  int32_t code = TSDB_CODE_SUCCESS;
5,868,337✔
3543
  int32_t lino = 0;
5,868,337✔
3544
  SStmStatus* pStream = (SStmStatus*)pStatus->pStream;
5,868,337✔
3545

3546
  if (1 == atomic_val_compare_exchange_8(&pStream->triggerNeedUpdate, 1, 0)) {
5,868,337✔
3547
    TAOS_CHECK_EXIT(msmGrpAddActionUpdateTrigger(pCtx->actionStm, pTask->streamId));
×
3548
  }
3549
  
3550
  SArray* userRecalcList = NULL;
5,868,337✔
3551
  if (atomic_load_ptr(&pStream->userRecalcList)) {
5,868,337✔
3552
    taosWLockLatch(&pStream->userRecalcLock);
3,488✔
3553
    if (pStream->userRecalcList) {
3,488✔
3554
      userRecalcList = pStream->userRecalcList;
3,488✔
3555
      pStream->userRecalcList = NULL;
3,488✔
3556
    }
3557
    taosWUnLockLatch(&pStream->userRecalcLock);
3,488✔
3558
    
3559
    if (userRecalcList) {
3,488✔
3560
      TAOS_CHECK_EXIT(msmGrpAddActionRecalc(pCtx, pTask->streamId, userRecalcList));
3,488✔
3561
    }
3562
  }
3563

3564
  if (pTask->detailStatus >= 0 && pCtx->pReq->pTriggerStatus) {
5,868,337✔
3565
    (void)mstWaitLock(&pStatus->detailStatusLock, false);
2,924,450✔
3566
    if (NULL == pStatus->detailStatus) {
2,924,450✔
3567
      pStatus->detailStatus = taosMemoryCalloc(1, sizeof(SSTriggerRuntimeStatus));
200,049✔
3568
      if (NULL == pStatus->detailStatus) {
200,049✔
3569
        taosWUnLockLatch(&pStatus->detailStatusLock);
×
3570
        TSDB_CHECK_NULL(pStatus->detailStatus, code, lino, _exit, terrno);
×
3571
      }
3572
    }
3573
    
3574
    memcpy(pStatus->detailStatus, taosArrayGet(pCtx->pReq->pTriggerStatus, pTask->detailStatus), sizeof(SSTriggerRuntimeStatus));
2,924,450✔
3575
    taosWUnLockLatch(&pStatus->detailStatusLock);
2,924,450✔
3576
  }
3577

3578
_exit:
2,943,887✔
3579

3580
  if (code) {
5,868,337✔
3581
    // IGNORE STOP STREAM BY ERROR
3582
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3583
  }
3584
}
5,868,337✔
3585

3586
int32_t msmNormalHandleStatusUpdate(SStmGrpCtx* pCtx) {
1,337,156✔
3587
  int32_t code = TSDB_CODE_SUCCESS;
1,337,156✔
3588
  int32_t lino = 0;
1,337,156✔
3589
  int32_t num = taosArrayGetSize(pCtx->pReq->pStreamStatus);
1,337,156✔
3590

3591
  mstDebug("NORMAL: start to handle stream group %d tasks status, taskNum:%d", pCtx->pReq->streamGId, num);
1,337,156✔
3592

3593
  for (int32_t i = 0; i < num; ++i) {
50,628,645✔
3594
    SStmTaskStatusMsg* pTask = taosArrayGet(pCtx->pReq->pStreamStatus, i);
49,291,489✔
3595
    msttDebug("task status %s got on dnode %d, taskIdx:%d", gStreamStatusStr[pTask->status], pCtx->pReq->dnodeId, pTask->taskIdx);
49,291,489✔
3596
    
3597
    SStmTaskStatus** ppStatus = taosHashGet(mStreamMgmt.taskMap, &pTask->streamId, sizeof(pTask->streamId) + sizeof(pTask->taskId));
49,291,489✔
3598
    if (NULL == ppStatus) {
49,291,489✔
3599
      msttWarn("task no longer exists in taskMap, streamId:0x%" PRIx64 " taskId:0x%" PRIx64 " type:%s status:%s taskIdx:%d",
1,650✔
3600
          (uint64_t)pTask->streamId, (uint64_t)pTask->taskId, gStreamTaskTypeStr[pTask->type], gStreamStatusStr[pTask->status], pTask->taskIdx);
3601
      msmHandleStreamTaskErr(pCtx, STM_ERR_TASK_NOT_EXISTS, pTask);
1,650✔
3602
      continue;
1,650✔
3603
    }
3604

3605
    SStmStatus* pStream = (SStmStatus*)(*ppStatus)->pStream;
49,289,839✔
3606
    int8_t stopped = atomic_load_8(&pStream->stopped);
49,289,839✔
3607
    if (stopped) {
49,289,839✔
3608
      msttWarn("stream already stopped %d, will try to undeploy current task, taskIdx:%d", stopped, pTask->taskIdx);
255,223✔
3609
      msmHandleStreamTaskErr(pCtx, STM_ERR_STREAM_STOPPED, pTask);
255,223✔
3610
      continue;
255,223✔
3611
    }
3612

3613
    if ((pTask->seriousId != (*ppStatus)->id.seriousId) || (pTask->nodeId != (*ppStatus)->id.nodeId)) {
49,034,616✔
3614
      msttInfo("task mismatch with it in taskMap, will try to rm it, current seriousId:%" PRId64 ", nodeId:%d", 
×
3615
          (*ppStatus)->id.seriousId, (*ppStatus)->id.nodeId);
3616
          
3617
      msmHandleStreamTaskErr(pCtx, STM_ERR_TASK_NOT_EXISTS, pTask);
×
3618
      continue;
×
3619
    }
3620

3621
    if ((*ppStatus)->status != pTask->status) {
49,034,616✔
3622
      if (STREAM_STATUS_RUNNING == pTask->status) {
2,671,751✔
3623
        (*ppStatus)->runningStartTs = pCtx->currTs;
1,144,985✔
3624
      } else if (MST_IS_RUNNER_GETTING_READY(pTask) && STREAM_IS_REDEPLOY_RUNNER((*ppStatus)->flags)) {
1,526,766✔
3625
        if (pStream->triggerTask) {
×
3626
          atomic_store_8(&pStream->triggerNeedUpdate, 1);
×
3627
        }
3628
        
3629
        STREAM_CLR_FLAG((*ppStatus)->flags, STREAM_FLAG_REDEPLOY_RUNNER);
×
3630
      }
3631
    }
3632
    
3633
    (*ppStatus)->errCode = pTask->errorCode;
49,034,616✔
3634
    (*ppStatus)->status = pTask->status;
49,034,616✔
3635
    (*ppStatus)->lastUpTs = pCtx->currTs;
49,034,616✔
3636
    
3637
    if (STREAM_TRIGGER_TASK == pTask->type && STREAM_STATUS_RUNNING == pTask->status) {
49,034,616✔
3638
      mstInfo("streamId:0x%" PRIx64 " trigger task status updated to Running in streamMap", (uint64_t)pTask->streamId);
5,460,777✔
3639
    }
3640
    
3641
    if (STREAM_STATUS_RUNNING != pTask->status) {
49,034,616✔
3642
      msmHandleTaskAbnormalStatus(pCtx, pTask, *ppStatus);
14,744,595✔
3643
    }
3644
    
3645
    if (STREAM_TRIGGER_TASK == pTask->type) {
49,034,616✔
3646
      msmChkHandleTriggerOperations(pCtx, pTask, *ppStatus);
5,868,337✔
3647
    }
3648
  }
3649

3650
_exit:
1,337,156✔
3651

3652
  if (code) {
1,337,156✔
3653
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3654
  }
3655

3656
  return code;
1,337,156✔
3657
}
3658

3659
int32_t msmWatchRecordNewTask(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
×
3660
  int32_t code = TSDB_CODE_SUCCESS;
×
3661
  int32_t lino = 0;
×
3662
  int64_t streamId = pTask->streamId;
×
3663
  SStreamObj* pStream = NULL;
×
3664

3665
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3666
  if (NULL == pStatus) {
×
3667
    SStmStatus status = {0};
×
3668
    TAOS_CHECK_EXIT(mndAcquireStreamById(pCtx->pMnode, streamId, &pStream));
×
3669
    TSDB_CHECK_NULL(pStream, code, lino, _exit, TSDB_CODE_MND_STREAM_NOT_EXIST);
×
3670
    if (STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags) || pStream->pCreate->vtableCalc) {
×
3671
      mndReleaseStream(pCtx->pMnode, pStream);
×
3672
      msttDebug("virtual table task ignored, triggerTblType:%d, vtableCalc:%dstatus:%s", 
×
3673
          pStream->pCreate->triggerTblType, pStream->pCreate->vtableCalc, gStreamStatusStr[pTask->status]);
3674
      return code;
×
3675
    }
3676

3677
    TAOS_CHECK_EXIT(msmInitStmStatus(pCtx, &status, pStream, true));
×
3678
    mndReleaseStream(pCtx->pMnode, pStream);
×
3679

3680
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.streamMap, &streamId, sizeof(streamId), &status, sizeof(status)));
×
3681
    pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3682
    TSDB_CHECK_NULL(pStatus, code, lino, _exit, terrno);
×
3683
    msttDebug("stream added to streamMap cause of new task status:%s", gStreamStatusStr[pTask->status]);
×
3684
  }
3685

3686
  SStmTaskStatus* pNewTask = NULL;
×
3687
  switch (pTask->type) {
×
3688
    case STREAM_READER_TASK: {
×
3689
      void* pList = STREAM_IS_TRIGGER_READER(pTask->flags) ? (void*)pStatus->trigReaders : (void*)pStatus->calcReaders;
×
3690
      if (NULL == pList) {
×
3691
        mstsError("%sReader list is NULL", STREAM_IS_TRIGGER_READER(pTask->flags) ? "trig" : "calc");
×
3692
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3693
      }
3694
      int32_t readerSize = STREAM_IS_TRIGGER_READER(pTask->flags) ? pStatus->trigReaderNum : pStatus->calcReaderNum;
×
3695
      if ((STREAM_IS_TRIGGER_READER(pTask->flags) && taosArrayGetSize(pList) >= readerSize) ||
×
3696
          MST_LIST_SIZE((SList*)pList) >= readerSize){
×
3697
        mstsError("%sReader list is already full, size:%d, expSize:%d", STREAM_IS_TRIGGER_READER(pTask->flags) ? "trig" : "calc",
×
3698
            (int32_t)taosArrayGetSize(pList), readerSize);
3699
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3700
      }
3701
      
3702
      SStmTaskStatus taskStatus = {0};
×
3703
      taskStatus.pStream = pStatus;
×
3704
      mstSetTaskStatusFromMsg(pCtx, &taskStatus, pTask);
×
3705
      if (STREAM_IS_TRIGGER_READER(pTask->flags)) {
×
3706
        pNewTask = taosArrayPush(pList, &taskStatus);
×
3707
        TSDB_CHECK_NULL(pNewTask, code, lino, _exit, terrno);
×
3708
      } else {
3709
        TAOS_CHECK_EXIT(tdListAppend(pStatus->calcReaders, &taskStatus));
×
3710
        SListNode* pTailNode = tdListGetTail(pStatus->calcReaders);
×
3711
        QUERY_CHECK_NULL(pTailNode, code, lino, _exit, TSDB_CODE_INTERNAL_ERROR);
×
3712
        pNewTask = (SStmTaskStatus*)pTailNode->data;
×
3713
      }
3714
      
3715
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pNewTask));
×
3716
      TAOS_CHECK_EXIT(msmSTAddToVgroupMapImpl(streamId, pNewTask, STREAM_IS_TRIGGER_READER(pTask->flags)));
×
3717
      break;
×
3718
    }
3719
    case STREAM_TRIGGER_TASK: {
×
3720
      taosMemoryFreeClear(pStatus->triggerTask);
×
3721
      pStatus->triggerTask = taosMemoryCalloc(1, sizeof(*pStatus->triggerTask));
×
3722
      TSDB_CHECK_NULL(pStatus->triggerTask, code, lino, _exit, terrno);
×
3723
      pStatus->triggerTask->pStream = pStatus;
×
3724
      mstSetTaskStatusFromMsg(pCtx, pStatus->triggerTask, pTask);
×
3725
      pNewTask = pStatus->triggerTask;
×
3726

3727
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pNewTask));
×
3728
      TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pNewTask, 0));
×
3729
      break;
×
3730
    }
3731
    case STREAM_RUNNER_TASK:{
×
3732
      if (NULL == pStatus->runners[pTask->deployId]) {
×
3733
        mstsError("deploy %d runner list is NULL", pTask->deployId);
×
3734
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3735
      }
3736
      if (taosArrayGetSize(pStatus->runners[pTask->deployId]) >= pStatus->runnerNum) {
×
3737
        mstsError("deploy %d runner list is already full, size:%d, expSize:%d", pTask->deployId, 
×
3738
            (int32_t)taosArrayGetSize(pStatus->runners[pTask->deployId]), pStatus->runnerNum);
3739
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3740
      }    
3741
      
3742
      SStmTaskStatus taskStatus = {0};
×
3743
      taskStatus.pStream = pStatus;
×
3744
      mstSetTaskStatusFromMsg(pCtx, &taskStatus, pTask);
×
3745
      pNewTask = taosArrayPush(pStatus->runners[pTask->deployId], &taskStatus);
×
3746
      TSDB_CHECK_NULL(pNewTask, code, lino, _exit, terrno);
×
3747

3748
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pNewTask));
×
3749
      TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pNewTask, pTask->deployId));
×
3750
      break;
×
3751
    }
3752
    default: {
×
3753
      msttError("invalid task type:%d in task status", pTask->type);
×
3754
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3755
      break;
×
3756
    }
3757
  }
3758

3759
_exit:
×
3760

3761
  if (code) {
×
3762
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3763
  } else {
3764
    msttDebug("new task recored to taskMap/streamMap, task status:%s", gStreamStatusStr[pTask->status]);
×
3765
  }
3766

3767
  return code;
×
3768
}
3769

3770
int32_t msmWatchHandleStatusUpdate(SStmGrpCtx* pCtx) {
×
3771
  int32_t code = TSDB_CODE_SUCCESS;
×
3772
  int32_t lino = 0;
×
3773
  int32_t num = taosArrayGetSize(pCtx->pReq->pStreamStatus);
×
3774

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

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

3781
    if (pTask->taskId >= mStreamMgmt.lastTaskId) {
×
3782
      mStreamMgmt.lastTaskId = pTask->taskId + 1;
×
3783
    }
3784
    
3785
    SStmTaskStatus** ppStatus = taosHashGet(mStreamMgmt.taskMap, &pTask->streamId, sizeof(pTask->streamId) + sizeof(pTask->taskId));
×
3786
    if (NULL == ppStatus) {
×
3787
      msttInfo("task still not in taskMap, will try to add it, taskIdx:%d", pTask->taskIdx);
×
3788
      
3789
      TAOS_CHECK_EXIT(msmWatchRecordNewTask(pCtx, pTask));
×
3790
      
3791
      continue;
×
3792
    }
3793
    
3794
    (*ppStatus)->status = pTask->status;
×
3795
    (*ppStatus)->lastUpTs = pCtx->currTs;
×
3796
  }
3797

3798
_exit:
×
3799

3800
  if (code) {
×
3801
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3802
  }
3803

3804
  return code;
×
3805
}
3806

3807
void msmRspAddStreamStart(int64_t streamId, SStmGrpCtx* pCtx, int32_t streamNum, SStmAction *pAction) {
200,562✔
3808
  int32_t code = TSDB_CODE_SUCCESS;
200,562✔
3809
  int32_t lino = 0;
200,562✔
3810
  if (NULL == pCtx->pRsp->start.taskList) {
200,562✔
3811
    pCtx->pRsp->start.taskList = taosArrayInit(streamNum, sizeof(SStreamTaskStart));
101,763✔
3812
    TSDB_CHECK_NULL(pCtx->pRsp->start.taskList, code, lino, _exit, terrno);
101,763✔
3813
  }
3814

3815
  SStmTaskId* pId = &pAction->start.triggerId;
200,562✔
3816
  SStreamTaskStart start = {0};
200,562✔
3817
  start.task.type = STREAM_TRIGGER_TASK;
200,562✔
3818
  start.task.streamId = streamId;
200,562✔
3819
  start.task.taskId = pId->taskId;
200,562✔
3820
  start.task.seriousId = pId->seriousId;
200,562✔
3821
  start.task.nodeId = pId->nodeId;
200,562✔
3822
  start.task.taskIdx = pId->taskIdx;
200,562✔
3823

3824
  TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->start.taskList, &start), code, lino, _exit, terrno);
401,124✔
3825
  TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(streamId, pCtx->currTs));
200,562✔
3826

3827
  mstsDebug("stream START added to dnode %d hb rsp, triggerTaskId:%" PRIx64, pId->nodeId, pId->taskId);
200,562✔
3828

3829
  return;
200,562✔
3830

3831
_exit:
×
3832

3833
  mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3834
}
3835

3836

3837
void msmRspAddStreamUndeploy(int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
49,892✔
3838
  int32_t code = TSDB_CODE_SUCCESS;
49,892✔
3839
  int32_t lino = 0;
49,892✔
3840
  int32_t dropNum = taosArrayGetSize(pAction->undeploy.taskList);
49,892✔
3841
  if (NULL == pCtx->pRsp->undeploy.taskList) {
49,892✔
3842
    pCtx->pRsp->undeploy.taskList = taosArrayInit(dropNum, sizeof(SStreamTaskUndeploy));
35,111✔
3843
    TSDB_CHECK_NULL(pCtx->pRsp->undeploy.taskList, code, lino, _exit, terrno);
35,111✔
3844
  }
3845

3846
  SStreamTaskUndeploy undeploy;
49,892✔
3847
  for (int32_t i = 0; i < dropNum; ++i) {
306,973✔
3848
    SStreamTask* pTask = (SStreamTask*)taosArrayGetP(pAction->undeploy.taskList, i);
257,081✔
3849
    undeploy.task = *pTask;
257,081✔
3850
    undeploy.undeployMsg.doCheckpoint = pAction->undeploy.doCheckpoint;
257,081✔
3851
    undeploy.undeployMsg.doCleanup = pAction->undeploy.doCleanup;
257,081✔
3852

3853
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->undeploy.taskList, &undeploy), code, lino, _exit, terrno);
514,162✔
3854
    TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(streamId, pCtx->currTs));
257,081✔
3855

3856
    msttDebug("task UNDEPLOY added to hb rsp, doCheckpoint:%d, doCleanup:%d", undeploy.undeployMsg.doCheckpoint, undeploy.undeployMsg.doCleanup);
257,081✔
3857
  }
3858

3859
  return;
49,892✔
3860

3861
_exit:
×
3862

3863
  mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3864
}
3865

3866
void msmRspAddTriggerUpdate(SMnode * pMnode, int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
×
3867
  int32_t code = TSDB_CODE_SUCCESS;
×
3868
  int32_t lino = 0;
×
3869

3870
  SStmStatus* pStream = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3871
  if (NULL == pStream) {
×
3872
    mstsDebug("stream already not exists in streamMap, ignore trigger update, streamRemain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
3873
    return;
×
3874
  }
3875

3876
  if (NULL == pStream->triggerTask) {
×
3877
    mstsWarn("no triggerTask exists, ignore trigger update, stopped:%d", atomic_load_8(&pStream->stopped));
×
3878
    return;
×
3879
  }
3880

3881
  SStreamMgmtRsp rsp = {0};
×
3882
  rsp.reqId = INT64_MIN;
×
3883
  rsp.header.msgType = STREAM_MSG_UPDATE_RUNNER;
×
3884
  rsp.task.streamId = streamId;
×
3885
  rsp.task.taskId = pStream->triggerTask->id.taskId;
×
3886

3887
  TAOS_CHECK_EXIT(msmBuildTriggerRunnerTargets(pMnode, pStream, streamId, &rsp.cont.runnerList));  
×
3888

3889
  if (NULL == pCtx->pRsp->rsps.rspList) {
×
3890
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
3891
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
×
3892
  }
3893

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

3896
_exit:
×
3897

3898
  if (code) {
×
3899
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3900
  } else {
3901
    mstsDebug("trigger update rsp added, runnerNum:%d", (int32_t)taosArrayGetSize(rsp.cont.runnerList));
×
3902
  }
3903
}
3904

3905
void msmRspAddUserRecalc(SMnode * pMnode, int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
3,488✔
3906
  int32_t code = TSDB_CODE_SUCCESS;
3,488✔
3907
  int32_t lino = 0;
3,488✔
3908

3909
  SStmStatus* pStream = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
3,488✔
3910
  if (NULL == pStream) {
3,488✔
3911
    mstsDebug("stream already not exists in streamMap, ignore trigger update, streamRemain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
3912
    return;
×
3913
  }
3914

3915
  if (NULL == pStream->triggerTask) {
3,488✔
3916
    mstsWarn("no triggerTask exists, ignore trigger update, stopped:%d", atomic_load_8(&pStream->stopped));
×
3917
    return;
×
3918
  }
3919

3920
  SStreamMgmtRsp rsp = {0};
3,488✔
3921
  rsp.reqId = INT64_MIN;
3,488✔
3922
  rsp.header.msgType = STREAM_MSG_USER_RECALC;
3,488✔
3923
  rsp.task.streamId = streamId;
3,488✔
3924
  rsp.task.taskId = pStream->triggerTask->id.taskId;
3,488✔
3925
  TSWAP(rsp.cont.recalcList, pAction->recalc.recalcList);
3,488✔
3926

3927
  if (NULL == pCtx->pRsp->rsps.rspList) {
3,488✔
3928
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
3,280✔
3929
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
3,280✔
3930
  }
3931

3932
  TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), code, lino, _exit, terrno);
6,976✔
3933

3934
_exit:
3,488✔
3935

3936
  if (code) {
3,488✔
3937
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3938
  } else {
3939
    mstsDebug("user recalc rsp added, recalcNum:%d", (int32_t)taosArrayGetSize(rsp.cont.recalcList));
3,488✔
3940
  }
3941
}
3942

3943

3944
int32_t msmHandleHbPostActions(SStmGrpCtx* pCtx) {
139,566✔
3945
  int32_t code = TSDB_CODE_SUCCESS;
139,566✔
3946
  int32_t lino = 0;
139,566✔
3947
  void* pIter = NULL;
139,566✔
3948
  int32_t streamNum = taosHashGetSize(pCtx->actionStm);
139,566✔
3949

3950
  mstDebug("start to handle stream group %d post actions", pCtx->pReq->streamGId);
139,566✔
3951

3952
  while (1) {
253,942✔
3953
    pIter = taosHashIterate(pCtx->actionStm, pIter);
393,508✔
3954
    if (pIter == NULL) {
393,508✔
3955
      break;
139,566✔
3956
    }
3957

3958
    int64_t* pStreamId = taosHashGetKey(pIter, NULL);
253,942✔
3959
    SStmAction *pAction = (SStmAction *)pIter;
253,942✔
3960
    
3961
    if (STREAM_ACT_UNDEPLOY & pAction->actions) {
253,942✔
3962
      msmRspAddStreamUndeploy(*pStreamId, pCtx, pAction);
49,892✔
3963
      continue;
49,892✔
3964
    }
3965

3966
    if (STREAM_ACT_UPDATE_TRIGGER & pAction->actions) {
204,050✔
3967
      msmRspAddTriggerUpdate(pCtx->pMnode, *pStreamId, pCtx, pAction);
×
3968
    }
3969

3970
    if (STREAM_ACT_RECALC & pAction->actions) {
204,050✔
3971
      msmRspAddUserRecalc(pCtx->pMnode, *pStreamId, pCtx, pAction);
3,488✔
3972
    }
3973

3974
    if (STREAM_ACT_START & pAction->actions) {
204,050✔
3975
      msmRspAddStreamStart(*pStreamId, pCtx, streamNum, pAction);
200,562✔
3976
    }
3977
  }
3978
  
3979
_exit:
139,566✔
3980

3981
  if (pIter) {
139,566✔
3982
    taosHashCancelIterate(pCtx->actionStm, pIter);
×
3983
  }
3984

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

3989
  return code;
139,566✔
3990
}
3991

3992
int32_t msmCheckUpdateDnodeTs(SStmGrpCtx* pCtx) {
17,687,156✔
3993
  int32_t  code = TSDB_CODE_SUCCESS;
17,687,156✔
3994
  int32_t  lino = 0;
17,687,156✔
3995
  int64_t* lastTs = NULL;
17,687,156✔
3996
  bool     noExists = false;
17,687,156✔
3997

3998
  while (true) {
3999
    lastTs = taosHashGet(mStreamMgmt.dnodeMap, &pCtx->pReq->dnodeId, sizeof(pCtx->pReq->dnodeId));
18,236,989✔
4000
    if (NULL == lastTs) {
18,236,989✔
4001
      if (noExists) {
714,805✔
4002
        mstWarn("Got unknown dnode %d hb msg, may be dropped", pCtx->pReq->dnodeId);
164,972✔
4003
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NODE_NOT_EXISTS);
164,972✔
4004
      }
4005

4006
      noExists = true;
549,833✔
4007
      TAOS_CHECK_EXIT(msmSTAddDnodesToMap(pCtx->pMnode));
549,833✔
4008
      
4009
      continue;
549,833✔
4010
    }
4011

4012
    while (true) {
×
4013
      int64_t lastTsValue = atomic_load_64(lastTs);
17,522,184✔
4014
      if (pCtx->currTs > lastTsValue) {
17,522,184✔
4015
        if (lastTsValue == atomic_val_compare_exchange_64(lastTs, lastTsValue, pCtx->currTs)) {
17,517,213✔
4016
          mstDebug("dnode %d lastUpTs updated", pCtx->pReq->dnodeId);
17,517,213✔
4017
          return code;
17,517,213✔
4018
        }
4019

4020
        continue;
×
4021
      }
4022

4023
      return code;
4,971✔
4024
    }
4025

4026
    break;
4027
  }
4028

4029
_exit:
164,972✔
4030

4031
  if (code) {
164,972✔
4032
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
164,972✔
4033
  }
4034

4035
  return code;  
164,972✔
4036
}
4037

4038
void msmWatchCheckStreamMap(SStmGrpCtx* pCtx) {
×
4039
  SStmStatus* pStatus = NULL;
×
4040
  int32_t trigReaderNum = 0;
×
4041
  int32_t calcReaderNum = 0;
×
4042
  int32_t runnerNum = 0;
×
4043
  int64_t streamId = 0;
×
4044
  void* pIter = NULL;
×
4045
  while (true) {
4046
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
×
4047
    if (NULL == pIter) {
×
4048
      return;
×
4049
    }
4050

4051
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
4052
    pStatus = (SStmStatus*)pIter;
×
4053

4054
    if (NULL == pStatus->triggerTask) {
×
4055
      mstsWarn("no trigger task recored, deployTimes:%" PRId64, pStatus->deployTimes);
×
4056
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
4057
      continue;
×
4058
    }
4059
    
4060
    trigReaderNum = taosArrayGetSize(pStatus->trigReaders);
×
4061
    if (pStatus->trigReaderNum != trigReaderNum) {
×
4062
      mstsWarn("trigReaderNum %d mis-match with expected %d", trigReaderNum, pStatus->trigReaderNum);
×
4063
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
4064
      continue;
×
4065
    }
4066

4067
    calcReaderNum = MST_LIST_SIZE(pStatus->calcReaders);
×
4068
    if (pStatus->calcReaderNum != calcReaderNum) {
×
4069
      mstsWarn("calcReaderNum %d mis-match with expected %d", calcReaderNum, pStatus->calcReaderNum);
×
4070
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
4071
      continue;
×
4072
    }
4073

4074
    for (int32_t i = 0; i < pStatus->runnerDeploys; ++i) {
×
4075
      runnerNum = taosArrayGetSize(pStatus->runners[i]);
×
4076
      if (runnerNum != pStatus->runnerNum) {
×
4077
        mstsWarn("runner deploy %d runnerNum %d mis-match with expected %d", i, runnerNum, pStatus->runnerNum);
×
4078
        msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
4079
        continue;
×
4080
      }
4081
    }
4082
  }
4083
}
4084

4085
int32_t msmWatchHandleEnding(SStmGrpCtx* pCtx, bool watchError) {
357✔
4086
  int32_t code = TSDB_CODE_SUCCESS;
357✔
4087
  int32_t lino = 0;
357✔
4088
  int32_t minVal = watchError ? 0 : 1;
357✔
4089

4090
  if (0 != atomic_val_compare_exchange_8(&mStreamMgmt.watch.ending, 0, 1)) {
357✔
4091
    return code;
×
4092
  }
4093

4094
  while (atomic_load_32(&mStreamMgmt.watch.processing) > minVal) {
357✔
4095
    (void)sched_yield();
×
4096
  }
4097

4098
  if (watchError) {
357✔
4099
    taosHashClear(mStreamMgmt.vgroupMap);
×
4100
    taosHashClear(mStreamMgmt.snodeMap);
×
4101
    taosHashClear(mStreamMgmt.taskMap);
×
4102
    taosHashClear(mStreamMgmt.streamMap);
×
4103
    mstInfo("watch error happends, clear all maps");
×
4104
    goto _exit;
×
4105
  }
4106

4107
  if (0 == atomic_load_8(&mStreamMgmt.watch.taskRemains)) {
357✔
4108
    mstInfo("no stream tasks remain during watch state");
357✔
4109
    goto _exit;
357✔
4110
  }
4111

4112
  msmWatchCheckStreamMap(pCtx);
×
4113

4114
_exit:
357✔
4115

4116
  mStreamMgmt.lastTaskId += 100000;
357✔
4117

4118
  mstInfo("watch state end, new taskId begin from:%" PRIx64, mStreamMgmt.lastTaskId);
357✔
4119

4120
  msmSetInitRuntimeState(MND_STM_STATE_NORMAL);
357✔
4121

4122
  if (code) {
357✔
4123
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4124
  }
4125

4126
  return code;
357✔
4127
}
4128

4129

4130
int32_t msmWatchHandleHbMsg(SStmGrpCtx* pCtx) {
12,209✔
4131
  int32_t code = TSDB_CODE_SUCCESS;
12,209✔
4132
  int32_t lino = 0;
12,209✔
4133
  SStreamHbMsg* pReq = pCtx->pReq;
12,209✔
4134

4135
  (void)atomic_add_fetch_32(&mStreamMgmt.watch.processing, 1);
12,209✔
4136
  
4137
  if (atomic_load_8(&mStreamMgmt.watch.ending)) {
12,209✔
4138
    goto _exit;
×
4139
  }
4140

4141
  TAOS_CHECK_EXIT(msmCheckUpdateDnodeTs(pCtx));
12,209✔
4142
  if (GOT_SNODE(pReq->snodeId)) {
12,209✔
4143
    TAOS_CHECK_EXIT(msmUpdateSnodeUpTs(pCtx));
2,129✔
4144
  }
4145

4146
  if (taosArrayGetSize(pReq->pStreamStatus) > 0) {
12,209✔
4147
    atomic_store_8(&mStreamMgmt.watch.taskRemains, 1);
×
4148
    TAOS_CHECK_EXIT(msmWatchHandleStatusUpdate(pCtx));
×
4149
  }
4150

4151
  if ((pCtx->currTs - MND_STREAM_GET_LAST_TS(STM_EVENT_ACTIVE_BEGIN)) > MST_SHORT_ISOLATION_DURATION) {
12,209✔
4152
    TAOS_CHECK_EXIT(msmWatchHandleEnding(pCtx, false));
357✔
4153
  }
4154

4155
_exit:
12,209✔
4156

4157
  atomic_sub_fetch_32(&mStreamMgmt.watch.processing, 1);
12,209✔
4158
  
4159
  if (code) {
12,209✔
4160
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4161

4162
    (void)msmWatchHandleEnding(pCtx, true);
×
4163
  }
4164

4165
  return code;
12,209✔
4166
}
4167

4168
int32_t msmGetTrigOReaderSize(SArray* pOReaders) {
6,347,446✔
4169
  int32_t listSize = taosArrayGetSize(pOReaders);
6,347,446✔
4170
  int32_t totalSize = 0;
6,347,446✔
4171
  
4172
  for (int32_t i = 0; i < listSize; ++i) {
7,610,977✔
4173
    SArray* pList = taosArrayGetP(pOReaders, i);
1,263,531✔
4174
    totalSize += taosArrayGetSize(pList);
1,263,531✔
4175
  }
4176

4177
  return totalSize;
6,347,446✔
4178
}
4179

4180
SStmTaskStatus* msmGetTrigOReader(SArray* pOReaders, int32_t idx) {
753,827✔
4181
  SArray* pList = taosArrayGetP(pOReaders, idx / MST_ORIGINAL_READER_LIST_SIZE);
753,827✔
4182
  if (NULL == pList) {
753,827✔
4183
    return NULL;
×
4184
  }
4185

4186
  return (SStmTaskStatus*)taosArrayGet(pList, idx % MST_ORIGINAL_READER_LIST_SIZE);
753,827✔
4187
}
4188

4189

4190
int32_t msmEnsureGetOReaderList(int64_t streamId, SStmStatus* pStatus, SArray** ppRes) {
62,508✔
4191
  int32_t code = TSDB_CODE_SUCCESS;
62,508✔
4192
  int32_t lino = 0;
62,508✔
4193

4194
  if (NULL == pStatus->trigOReaders) {
62,508✔
4195
    pStatus->trigOReaders = taosArrayInit(10, POINTER_BYTES);
54,265✔
4196
    TSDB_CHECK_NULL(pStatus->trigOReaders, code, lino, _exit, terrno);
54,265✔
4197
  }
4198

4199
  while (true) {
54,265✔
4200
    SArray** ppOReaderList = taosArrayGetLast(pStatus->trigOReaders);
116,773✔
4201

4202
    if (NULL == ppOReaderList || (*ppOReaderList)->size >= (*ppOReaderList)->capacity) {
116,773✔
4203
      SArray* pOReaderList = taosArrayInit(MST_ORIGINAL_READER_LIST_SIZE, sizeof(SStmTaskStatus));
54,265✔
4204
      TSDB_CHECK_NULL(pOReaderList, code, lino, _exit, terrno);
54,265✔
4205

4206
      TSDB_CHECK_NULL(taosArrayPush(pStatus->trigOReaders, &pOReaderList), code, lino, _exit, terrno);
108,530✔
4207
      continue;
54,265✔
4208
    }
4209

4210
    *ppRes = *ppOReaderList;
62,508✔
4211
    break;
62,508✔
4212
  }
4213

4214
_exit:
62,508✔
4215

4216
  if (code) {
62,508✔
4217
    mstsError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4218
  }
4219

4220
  return code;
62,508✔
4221
}
4222

4223
int32_t msmCheckDeployTrigReader(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStmTaskStatusMsg* pTask, int32_t vgId, int32_t vgNum) {
73,324✔
4224
  int32_t code = TSDB_CODE_SUCCESS;
73,324✔
4225
  int32_t lino = 0;
73,324✔
4226
  bool    readerExists = false;
73,324✔
4227
  int64_t streamId = pTask->streamId;
73,324✔
4228

4229
  int32_t readerNum = taosArrayGetSize(pStatus->trigReaders);
73,324✔
4230
  for (int32_t i = 0; i < readerNum; ++i) {
152,470✔
4231
    SStmTaskStatus* pReader = (SStmTaskStatus*)taosArrayGet(pStatus->trigReaders, i);
89,962✔
4232
    if (pReader->id.nodeId == vgId) {
89,962✔
4233
      readerExists = true;
10,816✔
4234
      break;
10,816✔
4235
    }
4236
  }
4237

4238
  if (!readerExists) {
73,324✔
4239
    SArray* pReaderList = NULL;
62,508✔
4240
    TAOS_CHECK_EXIT(msmEnsureGetOReaderList(streamId, pStatus, &pReaderList));
62,508✔
4241
    
4242
    SStmTaskStatus* pState = taosArrayReserve(pReaderList, 1);
62,508✔
4243
    TAOS_CHECK_EXIT(msmTDAddSingleTrigReader(pCtx, pState, vgId, pStatus, streamId));
62,508✔
4244
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pState));
62,508✔
4245
    TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, NULL, pState, true));
62,508✔
4246
  }
4247

4248
_exit:
10,816✔
4249

4250
  if (code) {
73,324✔
4251
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4252
  }
4253

4254
  return code;
73,324✔
4255
}
4256

4257
int32_t msmDeployTriggerOrigReader(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
64,457✔
4258
  int32_t code = TSDB_CODE_SUCCESS, finalCode = TSDB_CODE_SUCCESS;
64,457✔
4259
  int32_t lino = 0;
64,457✔
4260
  int32_t vgId = 0;
64,457✔
4261
  int64_t streamId = pTask->streamId;
64,457✔
4262
  SArray* pTbs = pTask->pMgmtReq->cont.pReqs;
64,457✔
4263
  int32_t tbNum = taosArrayGetSize(pTbs);
64,457✔
4264
  SStreamDbTableName* pName = NULL;
64,457✔
4265
  SSHashObj* pDbVgroups = NULL;
64,457✔
4266
  SStreamMgmtRsp rsp = {0};
64,457✔
4267
  rsp.reqId = pTask->pMgmtReq->reqId;
64,457✔
4268
  rsp.header.msgType = STREAM_MSG_ORIGTBL_READER_INFO;
64,457✔
4269
  int32_t iter = 0;
64,457✔
4270
  void* p = NULL;
64,457✔
4271
  SSHashObj* pVgs = NULL;
64,457✔
4272
  SStreamMgmtReq* pMgmtReq = NULL;
64,457✔
4273
  int8_t stopped = 0;
64,457✔
4274

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

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

4289
  if (rsp.reqId == pStatus->lastTrigMgmtReqId) {
64,457✔
4290
    mstsDebug("duplicated trigger oreader deploy msg, will ignore it, reqId %" PRId64, rsp.reqId);
×
4291
    goto _exit;
×
4292
  }
4293

4294
  atomic_store_64(&pStatus->lastTrigMgmtReqId, rsp.reqId); 
64,457✔
4295

4296
  stopped = atomic_load_8(&pStatus->stopped);
64,457✔
4297
  if (stopped) {
64,457✔
4298
    msttInfo("stream stopped %d, ignore deploy trigger reader, vgId:%d", stopped, vgId);
×
4299
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_STOPPED);
×
4300
  }
4301

4302
  if (tbNum <= 0) {
64,457✔
4303
    mstsWarn("empty table list in origReader req, array:%p", pTbs);
×
4304
    goto _exit;
×
4305
  }
4306

4307
  TAOS_CHECK_EXIT(mstBuildDBVgroupsMap(pCtx->pMnode, &pDbVgroups));
64,457✔
4308
  rsp.cont.vgIds = taosArrayInit(tbNum, sizeof(int32_t));
64,457✔
4309
  TSDB_CHECK_NULL(rsp.cont.vgIds, code, lino, _exit, terrno);
64,457✔
4310

4311
  pVgs = tSimpleHashInit(tbNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
64,457✔
4312
  TSDB_CHECK_NULL(pVgs, code, lino, _exit, terrno);
64,457✔
4313
  
4314
  for (int32_t i = 0; i < tbNum; ++i) {
253,776✔
4315
    pName = (SStreamDbTableName*)taosArrayGet(pTbs, i);
189,319✔
4316
    TAOS_CHECK_EXIT(mstGetTableVgId(pDbVgroups, pName->dbFName, pName->tbName, &vgId));
189,319✔
4317
    TSDB_CHECK_NULL(taosArrayPush(rsp.cont.vgIds, &vgId), code, lino, _exit, terrno);
378,638✔
4318
    TAOS_CHECK_EXIT(tSimpleHashPut(pVgs, &vgId, sizeof(vgId), &vgId, sizeof(vgId)));
189,319✔
4319
  }
4320

4321
  int32_t vgNum = tSimpleHashGetSize(pVgs);
64,457✔
4322
  while (true) {
4323
    p = tSimpleHashIterate(pVgs, p, &iter);
137,781✔
4324
    if (NULL == p) {
137,781✔
4325
      break;
64,457✔
4326
    }
4327
    
4328
    TAOS_CHECK_EXIT(msmCheckDeployTrigReader(pCtx, pStatus, pTask, *(int32_t*)p, vgNum));
73,324✔
4329
  }
4330
  
4331
  vgNum = msmGetTrigOReaderSize(pStatus->trigOReaders);
64,457✔
4332
  rsp.cont.readerList = taosArrayInit(vgNum, sizeof(SStreamTaskAddr));
64,457✔
4333
  TSDB_CHECK_NULL(rsp.cont.readerList, code, lino, _exit, terrno);
64,457✔
4334

4335
  SStreamTaskAddr addr;
64,457✔
4336
  for (int32_t i = 0; i < vgNum; ++i) {
126,965✔
4337
    SStmTaskStatus* pOTask = msmGetTrigOReader(pStatus->trigOReaders, i);
62,508✔
4338
    addr.taskId = pOTask->id.taskId;
62,508✔
4339
    addr.nodeId = pOTask->id.nodeId;
62,508✔
4340
    addr.epset = mndGetVgroupEpsetById(pCtx->pMnode, pOTask->id.nodeId);
62,508✔
4341
    TSDB_CHECK_NULL(taosArrayPush(rsp.cont.readerList, &addr), code, lino, _exit, terrno);
125,016✔
4342
    mstsDebug("the %dth otrigReader src added to trigger's virtual orig readerList, TASK:%" PRIx64 " nodeId:%d", i, addr.taskId, addr.nodeId);
62,508✔
4343
  }
4344

4345
_exit:
64,457✔
4346

4347
  tFreeSStreamMgmtReq(pMgmtReq);
64,457✔
4348
  taosMemoryFree(pMgmtReq);
64,457✔
4349

4350
  tSimpleHashCleanup(pVgs);
64,457✔
4351
  mstDestroyDbVgroupsHash(pDbVgroups);
64,457✔
4352

4353
  if (code) {
64,457✔
4354
    rsp.code = code;
×
4355
    
4356
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
×
4357

4358
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4359
  } else {
4360
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
128,914✔
4361
  }
4362

4363
_final:
64,457✔
4364

4365
  if (finalCode) {
64,457✔
4366
    tFreeSStreamMgmtRsp(&rsp);
×
4367
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code)); 
×
4368
    msmHandleStreamTaskErr(pCtx, STM_ERR_PROCESSING_ERR, pTask);
×
4369
  }
4370

4371
  return finalCode;
64,457✔
4372
}
4373

4374
int32_t msmGetCalcScanFromList(int64_t streamId, SArray* pList, int64_t uid, SStreamCalcScan** ppRes) {
2,464✔
4375
  int32_t num = taosArrayGetSize(pList);
2,464✔
4376
  SStreamCalcScan* pScan = NULL;
2,464✔
4377
  int32_t code = TSDB_CODE_SUCCESS, lino = 0;
2,464✔
4378
  int64_t planUid = 0;
2,464✔
4379
  for (int32_t i = 0; i < num; ++i) {
2,464✔
4380
    pScan = (SStreamCalcScan*)taosArrayGet(pList, i);
2,464✔
4381
    TAOS_CHECK_EXIT(mstGetScanUidFromPlan(streamId, pScan->scanPlan, &planUid));
2,464✔
4382
    if (0 != planUid && planUid == uid) {
2,464✔
4383
      *ppRes = pScan;
2,464✔
4384
      break;
2,464✔
4385
    }
4386
  }
4387

4388
_exit:
2,464✔
4389

4390
  if (code) {
2,464✔
4391
    mstsError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4392
  }
4393

4394
  return code;
2,464✔
4395
}
4396

4397
int32_t msmCheckDeployCalcReader(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStmTaskStatusMsg* pTask, int32_t vgId, int64_t uid, SStreamTaskAddr* pAddr) {
2,464✔
4398
  int32_t code = TSDB_CODE_SUCCESS;
2,464✔
4399
  int32_t lino = 0;
2,464✔
4400
  bool    readerExists = false;
2,464✔
4401
  int64_t streamId = pTask->streamId;
2,464✔
4402
  SListNode* pNode = listHead(pStatus->calcReaders);
2,464✔
4403
  SStmTaskStatus* pReader = NULL;
2,464✔
4404
  int32_t taskIdx = 0;
2,464✔
4405

4406
  int32_t readerNum = MST_LIST_SIZE(pStatus->calcReaders);
2,464✔
4407
  for (int32_t i = 0; i < readerNum; ++i, pNode = TD_DLIST_NODE_NEXT(pNode)) {
22,848✔
4408
    pReader = (SStmTaskStatus*)pNode->data;
20,384✔
4409
    if (pReader->id.nodeId == vgId && pReader->id.uid == uid) {
20,384✔
4410
      readerExists = true;
×
4411
      pAddr->taskId = pReader->id.taskId;
×
4412
      break;
×
4413
    }
4414
  }
4415

4416
  if (!readerExists) {
2,464✔
4417
    if (NULL == pStatus->calcReaders) {
2,464✔
4418
      pStatus->calcReaders = tdListNew(sizeof(SStmTaskStatus));
×
4419
      TSDB_CHECK_NULL(pStatus->calcReaders, code, lino, _exit, terrno);
×
4420
      taskIdx = 0;
×
4421
    } else {
4422
      pNode = listTail(pStatus->calcReaders);
2,464✔
4423
      pReader = (SStmTaskStatus*)pNode->data;
2,464✔
4424
      taskIdx = pReader->id.taskIdx + 1;
2,464✔
4425
    }
4426

4427
    SStreamCalcScan* pScan = NULL;
2,464✔
4428
    TAOS_CHECK_EXIT(msmGetCalcScanFromList(streamId, pStatus->pCreate->calcScanPlanList, uid, &pScan));
2,464✔
4429
    TSDB_CHECK_NULL(pScan, code, lino, _exit, TSDB_CODE_STREAM_INTERNAL_ERROR);
2,464✔
4430
    pReader = tdListReserve(pStatus->calcReaders);
2,464✔
4431
    TAOS_CHECK_EXIT(msmTDAddSingleCalcReader(pCtx, pReader, taskIdx, vgId, pScan->scanPlan, pStatus, streamId));
2,464✔
4432
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pReader));
2,464✔
4433
    TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, NULL, pReader, false));
2,464✔
4434
    pAddr->taskId = pReader->id.taskId;
2,464✔
4435
  }
4436

4437
  pAddr->epset = mndGetVgroupEpsetById(pCtx->pMnode, vgId);
2,464✔
4438
  pAddr->nodeId = vgId;
2,464✔
4439

4440
_exit:
2,464✔
4441

4442
  if (code) {
2,464✔
4443
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4444
  }
4445

4446
  return code;
2,464✔
4447
}
4448

4449

4450
int32_t msmDeployRunnerOrigReader(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
2,464✔
4451
  int32_t code = TSDB_CODE_SUCCESS, finalCode = TSDB_CODE_SUCCESS;
2,464✔
4452
  int32_t lino = 0;
2,464✔
4453
  int32_t vgId = 0;
2,464✔
4454
  int64_t streamId = pTask->streamId;
2,464✔
4455
  SArray* pReqs = pTask->pMgmtReq->cont.pReqs;
2,464✔
4456
  int32_t reqNum = taosArrayGetSize(pReqs);
2,464✔
4457
  SStreamOReaderDeployReq* pReq = NULL;
2,464✔
4458
  SStreamOReaderDeployRsp* pRsp = NULL;
2,464✔
4459
  SStreamMgmtRsp rsp = {0};
2,464✔
4460
  rsp.reqId = pTask->pMgmtReq->reqId;
2,464✔
4461
  rsp.header.msgType = STREAM_MSG_RUNNER_ORIGTBL_READER;
2,464✔
4462
  SStreamMgmtReq* pMgmtReq = NULL;
2,464✔
4463
  int8_t stopped = 0;
2,464✔
4464
  int32_t vgNum = 0;
2,464✔
4465
  SStreamTaskAddr* pAddr = NULL;
2,464✔
4466

4467
  if (NULL == pCtx->pRsp->rsps.rspList) {
2,464✔
4468
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
4469
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, finalCode, lino, _final, terrno);
×
4470
  }
4471
  
4472
  TSWAP(pTask->pMgmtReq, pMgmtReq);
2,464✔
4473
  rsp.task = *(SStreamTask*)pTask;
2,464✔
4474

4475
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
2,464✔
4476
  if (NULL == pStatus) {
2,464✔
4477
    mstsError("stream not deployed, remainStreams:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
4478
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_RUNNING);
×
4479
  }
4480

4481
  stopped = atomic_load_8(&pStatus->stopped);
2,464✔
4482
  if (stopped) {
2,464✔
4483
    msttInfo("stream stopped %d, ignore deploy trigger reader, vgId:%d", stopped, vgId);
×
4484
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_STOPPED);
×
4485
  }
4486

4487
  if (reqNum <= 0) {
2,464✔
4488
    mstsWarn("empty req list in origReader req, array:%p", pReqs);
×
4489
    goto _exit;
×
4490
  }
4491

4492
  rsp.cont.execRspList = taosArrayInit_s(sizeof(SStreamOReaderDeployRsp), reqNum);
2,464✔
4493
  TSDB_CHECK_NULL(rsp.cont.execRspList, code, lino, _exit, terrno);
2,464✔
4494

4495
  for (int32_t i = 0; i < reqNum; ++i) {
4,928✔
4496
    pReq = (SStreamOReaderDeployReq*)taosArrayGet(pReqs, i);
2,464✔
4497
    pRsp = (SStreamOReaderDeployRsp*)taosArrayGet(rsp.cont.execRspList, i);
2,464✔
4498
    pRsp->execId = pReq->execId;
2,464✔
4499
    vgNum = taosArrayGetSize(pReq->vgIds);
2,464✔
4500
    pRsp->vgList = taosArrayInit_s(sizeof(SStreamTaskAddr), vgNum);
2,464✔
4501
    TSDB_CHECK_NULL(pRsp->vgList, code, lino, _exit, terrno);
2,464✔
4502
    
4503
    for (int32_t n = 0; n < vgNum; ++n) {
4,928✔
4504
      vgId = *(int32_t*)taosArrayGet(pReq->vgIds, n);
2,464✔
4505
      pAddr = taosArrayGet(pRsp->vgList, n);
2,464✔
4506
      TAOS_CHECK_EXIT(msmCheckDeployCalcReader(pCtx, pStatus, pTask, vgId, pReq->uid, pAddr));
2,464✔
4507
    }
4508
  }
4509

4510
_exit:
2,464✔
4511

4512
  tFreeSStreamMgmtReq(pMgmtReq);
2,464✔
4513
  taosMemoryFree(pMgmtReq);
2,464✔
4514

4515
  if (code) {
2,464✔
4516
    rsp.code = code;
×
4517
    
4518
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
×
4519
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4520
  } else {
4521
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
4,928✔
4522
  }
4523

4524

4525
_final:
2,464✔
4526

4527
  if (finalCode) {
2,464✔
4528
    tFreeSStreamMgmtRsp(&rsp);
×
4529
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code)); 
×
4530
    msmHandleStreamTaskErr(pCtx, STM_ERR_PROCESSING_ERR, pTask);
×
4531
  }
4532

4533
  return finalCode;
2,464✔
4534
}
4535

4536

4537
int32_t msmHandleTaskMgmtReq(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
66,921✔
4538
  int32_t code = TSDB_CODE_SUCCESS;
66,921✔
4539
  int32_t lino = 0;
66,921✔
4540

4541
  switch (pTask->pMgmtReq->type) {
66,921✔
4542
    case STREAM_MGMT_REQ_TRIGGER_ORIGTBL_READER:
64,457✔
4543
      msmDeployTriggerOrigReader(pCtx, pTask);
64,457✔
4544
      break;
64,457✔
4545
    case STREAM_MGMT_REQ_RUNNER_ORIGTBL_READER:
2,464✔
4546
      msmDeployRunnerOrigReader(pCtx, pTask);
2,464✔
4547
      break;
2,464✔
4548
    default:
×
4549
      msttError("Invalid mgmtReq type:%d", pTask->pMgmtReq->type);
×
4550
      code = TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
4551
      break;
×
4552
  }
4553

4554
_exit:
66,921✔
4555

4556
  if (code) {
66,921✔
4557
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4558
  }
4559

4560
  return code;
66,921✔
4561
}
4562

4563
int32_t msmHandleStreamRequests(SStmGrpCtx* pCtx) {
21,807✔
4564
  int32_t code = TSDB_CODE_SUCCESS;
21,807✔
4565
  int32_t lino = 0;
21,807✔
4566
  SStreamHbMsg* pReq = pCtx->pReq;
21,807✔
4567
  SStmTaskStatusMsg* pTask = NULL;
21,807✔
4568
  
4569
  int32_t reqNum = taosArrayGetSize(pReq->pStreamReq);
21,807✔
4570
  if (reqNum > 0 && NULL == pCtx->pRsp->rsps.rspList) {
21,807✔
4571
    pCtx->pRsp->rsps.rspList = taosArrayInit(reqNum, sizeof(SStreamMgmtRsp));
21,807✔
4572
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
21,807✔
4573
  }
4574
  
4575
  for (int32_t i = 0; i < reqNum; ++i) {
88,728✔
4576
    int32_t idx = *(int32_t*)taosArrayGet(pReq->pStreamReq, i);
66,921✔
4577
    pTask = (SStmTaskStatusMsg*)taosArrayGet(pReq->pStreamStatus, idx);
66,921✔
4578
    if (NULL == pTask) {
66,921✔
4579
      mstError("idx %d is NULL, reqNum:%d", idx, reqNum);
×
4580
      continue;
×
4581
    }
4582

4583
    if (NULL == pTask->pMgmtReq) {
66,921✔
4584
      msttError("idx %d without mgmtReq", idx);
×
4585
      continue;
×
4586
    }
4587

4588
    TAOS_CHECK_EXIT(msmHandleTaskMgmtReq(pCtx, pTask));
66,921✔
4589
  }
4590

4591
_exit:
21,807✔
4592

4593
  if (code) {
21,807✔
4594
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4595
  }
4596

4597
  return code;
21,807✔
4598
}
4599

4600
int32_t msmNormalHandleHbMsg(SStmGrpCtx* pCtx) {
17,674,947✔
4601
  int32_t code = TSDB_CODE_SUCCESS;
17,674,947✔
4602
  int32_t lino = 0;
17,674,947✔
4603
  SStreamHbMsg* pReq = pCtx->pReq;
17,674,947✔
4604

4605
  TAOS_CHECK_EXIT(msmCheckUpdateDnodeTs(pCtx));
17,674,947✔
4606
  if (GOT_SNODE(pReq->snodeId)) {
17,509,975✔
4607
    TAOS_CHECK_EXIT(msmUpdateSnodeUpTs(pCtx));
1,500,223✔
4608
  }
4609
  
4610
  if (atomic_load_64(&mStreamMgmt.actionQ->qRemainNum) > 0 && 0 == taosWTryLockLatch(&mStreamMgmt.actionQLock)) {
17,509,739✔
4611
    msmHandleStreamActions(pCtx);
54,860✔
4612
    taosWUnLockLatch(&mStreamMgmt.actionQLock);
54,860✔
4613
  }
4614

4615
  if (taosArrayGetSize(pReq->pStreamReq) > 0 && mstWaitLock(&mStreamMgmt.actionQLock, false)) {
17,509,739✔
4616
    code = msmHandleStreamRequests(pCtx);
21,807✔
4617
    taosWUnLockLatch(&mStreamMgmt.actionQLock);
21,807✔
4618
    TAOS_CHECK_EXIT(code);
21,807✔
4619
  }
4620

4621
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
17,509,739✔
4622
    TAOS_CHECK_EXIT(msmGrpAddDeployVgTasks(pCtx));
79,346✔
4623
  } else {
4624
    TAOS_CHECK_EXIT(msmUpdateVgroupsUpTs(pCtx));
17,430,393✔
4625
  }
4626

4627
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0 && GOT_SNODE(pReq->snodeId)) {
17,509,739✔
4628
    TAOS_CHECK_EXIT(msmGrpAddDeploySnodeTasks(pCtx));
119,766✔
4629
  }
4630

4631
  if (taosHashGetSize(pCtx->deployStm) > 0) {
17,509,739✔
4632
    TAOS_CHECK_EXIT(msmRspAddStreamsDeploy(pCtx));
78,457✔
4633
  }
4634

4635
  if (taosArrayGetSize(pReq->pStreamStatus) > 0) {
17,509,739✔
4636
    TAOS_CHECK_EXIT(msmNormalHandleStatusUpdate(pCtx));
1,337,156✔
4637
  }
4638

4639
  if (taosHashGetSize(pCtx->actionStm) > 0) {
17,509,739✔
4640
    TAOS_CHECK_EXIT(msmHandleHbPostActions(pCtx));
139,566✔
4641
  }
4642

4643
_exit:
17,509,739✔
4644

4645
  if (code) {
17,674,947✔
4646
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
165,208✔
4647
  }
4648

4649
  return code;
17,674,947✔
4650
}
4651

4652
void msmEncodeStreamHbRsp(int32_t code, SRpcHandleInfo *pRpcInfo, SMStreamHbRspMsg* pRsp, SRpcMsg* pMsg) {
17,761,871✔
4653
  int32_t lino = 0;
17,761,871✔
4654
  int32_t tlen = 0;
17,761,871✔
4655
  void   *buf = NULL;
17,761,871✔
4656

4657
  if (TSDB_CODE_SUCCESS != code) {
17,761,871✔
4658
    goto _exit;
165,208✔
4659
  }
4660

4661
  tEncodeSize(tEncodeStreamHbRsp, pRsp, tlen, code);
17,596,663✔
4662
  if (code < 0) {
17,596,663✔
4663
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(code));
×
4664
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
4665
  }
4666

4667
  buf = rpcMallocCont(tlen + sizeof(SStreamMsgGrpHeader));
17,596,663✔
4668
  if (buf == NULL) {
17,596,663✔
4669
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(terrno));
×
4670
    TAOS_CHECK_EXIT(terrno);    
×
4671
  }
4672

4673
  ((SStreamMsgGrpHeader *)buf)->streamGid = pRsp->streamGId;
17,596,663✔
4674
  void *abuf = POINTER_SHIFT(buf, sizeof(SStreamMsgGrpHeader));
17,596,663✔
4675

4676
  SEncoder encoder;
17,594,096✔
4677
  tEncoderInit(&encoder, abuf, tlen);
17,596,663✔
4678
  if ((code = tEncodeStreamHbRsp(&encoder, pRsp)) < 0) {
17,596,663✔
4679
    rpcFreeCont(buf);
×
4680
    buf = NULL;
×
4681
    tEncoderClear(&encoder);
×
4682
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(code));
×
4683
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
4684
  }
4685
  tEncoderClear(&encoder);
17,596,663✔
4686

4687
_exit:
17,761,871✔
4688

4689
  pMsg->code = code;
17,761,871✔
4690
  pMsg->info = *pRpcInfo;
17,761,871✔
4691
  if (TSDB_CODE_SUCCESS == code) {
17,761,871✔
4692
    pMsg->contLen = tlen + sizeof(SStreamMsgGrpHeader);
17,596,663✔
4693
    pMsg->pCont = buf;
17,596,663✔
4694
  }
4695
}
17,761,871✔
4696

4697

4698
int32_t msmHandleStreamHbMsg(SMnode* pMnode, int64_t currTs, SStreamHbMsg* pHb, SRpcMsg *pReq, SRpcMsg* pRspMsg) {
17,761,871✔
4699
  int32_t code = TSDB_CODE_SUCCESS;
17,761,871✔
4700
  SMStreamHbRspMsg rsp = {0};
17,761,871✔
4701
  rsp.streamGId = pHb->streamGId;
17,761,871✔
4702

4703
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, true);
17,761,871✔
4704

4705
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
17,761,871✔
4706
    mstWarn("mnode stream become NOT active, ignore stream hb from dnode %d streamGid %d", pHb->dnodeId, pHb->streamGId);
74,715✔
4707
    goto _exit;
74,715✔
4708
  }
4709

4710
  int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pHb->streamGId);
17,687,156✔
4711
  SStmGrpCtx* pCtx = &mStreamMgmt.tCtx[tidx].grpCtx[pHb->streamGId];
17,687,156✔
4712

4713
  pCtx->tidx = tidx;
17,687,156✔
4714
  pCtx->pMnode = pMnode;
17,687,156✔
4715
  pCtx->currTs = currTs;
17,687,156✔
4716
  pCtx->pReq = pHb;
17,687,156✔
4717
  pCtx->pRsp = &rsp;
17,687,156✔
4718
  pCtx->deployStm = mStreamMgmt.tCtx[pCtx->tidx].deployStm[pHb->streamGId];
17,687,156✔
4719
  pCtx->actionStm = mStreamMgmt.tCtx[pCtx->tidx].actionStm[pHb->streamGId];
17,687,156✔
4720
  
4721
  switch (atomic_load_8(&mStreamMgmt.state)) {
17,687,156✔
4722
    case MND_STM_STATE_WATCH:
12,209✔
4723
      code = msmWatchHandleHbMsg(pCtx);
12,209✔
4724
      break;
12,209✔
4725
    case MND_STM_STATE_NORMAL:
17,674,947✔
4726
      code = msmNormalHandleHbMsg(pCtx);
17,674,947✔
4727
      break;
17,674,947✔
4728
    default:
×
4729
      mstError("Invalid stream state: %d", mStreamMgmt.state);
×
4730
      code = TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
4731
      break;
×
4732
  }
4733

4734
_exit:
17,761,871✔
4735

4736
  msmEncodeStreamHbRsp(code, &pReq->info, &rsp, pRspMsg);
17,761,871✔
4737

4738
  msmCleanStreamGrpCtx(pHb);
17,761,871✔
4739
  msmClearStreamToDeployMaps(pHb);
17,761,871✔
4740

4741
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
17,761,871✔
4742
  
4743
  tFreeSMStreamHbRspMsg(&rsp);
17,761,871✔
4744

4745
  return code;
17,761,871✔
4746
}
4747

4748
void msmHandleBecomeLeader(SMnode *pMnode) {
433,607✔
4749
  if (tsDisableStream) {
433,607✔
4750
    return;
×
4751
  }
4752

4753
  mstInfo("start to process mnode become leader");
433,607✔
4754

4755
  int32_t code = 0;
433,607✔
4756
  streamAddVnodeLeader(MNODE_HANDLE);
433,607✔
4757
  
4758
  taosWLockLatch(&mStreamMgmt.runtimeLock);
433,607✔
4759
  msmDestroyRuntimeInfo(pMnode);
433,607✔
4760
  code = msmInitRuntimeInfo(pMnode);
433,607✔
4761
  taosWUnLockLatch(&mStreamMgmt.runtimeLock);
433,607✔
4762

4763
  if (TSDB_CODE_SUCCESS == code) {
433,607✔
4764
    atomic_store_8(&mStreamMgmt.active, 1);
433,607✔
4765
  }
4766

4767
  mstInfo("mnode stream mgmt active:%d", atomic_load_8(&mStreamMgmt.active));
433,607✔
4768
}
4769

4770
void msmHandleBecomeNotLeader(SMnode *pMnode) {  
528,487✔
4771
  if (tsDisableStream) {
528,487✔
4772
    return;
×
4773
  }
4774

4775
  mstInfo("start to process mnode become not leader");
528,487✔
4776

4777
  streamRemoveVnodeLeader(MNODE_HANDLE);
528,487✔
4778

4779
  if (atomic_val_compare_exchange_8(&mStreamMgmt.active, 1, 0)) {
528,487✔
4780
    taosWLockLatch(&mStreamMgmt.runtimeLock);
433,607✔
4781
    msmDestroyRuntimeInfo(pMnode);
433,607✔
4782
    mStreamMgmt.stat.inactiveTimes++;
433,607✔
4783
    taosWUnLockLatch(&mStreamMgmt.runtimeLock);
433,607✔
4784
  }
4785
}
4786

4787

4788
static void msmRedeployStream(int64_t streamId, SStmStatus* pStatus) {
×
4789
  if (1 == atomic_val_compare_exchange_8(&pStatus->stopped, 1, 0)) {
×
4790
    mstsInfo("try to reset and redeploy stream, deployTimes:%" PRId64, pStatus->deployTimes);
×
4791
    mstPostStreamAction(mStreamMgmt.actionQ, streamId, pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
×
4792
  } else {
4793
    mstsWarn("stream stopped %d already changed", atomic_load_8(&pStatus->stopped));
×
4794
  }
4795
}
×
4796

4797
static bool msmCheckStreamAssign(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
8,147✔
4798
  int32_t code = TSDB_CODE_SUCCESS;
8,147✔
4799
  int32_t lino = 0;
8,147✔
4800
  SStreamObj* pStream = pObj;
8,147✔
4801
  SSnodeObj* pSnode = p1;
8,147✔
4802
  SArray** ppRes = p2;
8,147✔
4803

4804
  if (pStream->mainSnodeId == pSnode->id) {
8,147✔
4805
    if (NULL == *ppRes) {
4,566✔
4806
      int32_t streamNum = sdbGetSize(pMnode->pSdb, SDB_STREAM);
860✔
4807
      *ppRes = taosArrayInit(streamNum, POINTER_BYTES);
860✔
4808
      TSDB_CHECK_NULL(*ppRes, code, lino, _exit, terrno);
860✔
4809
    }
4810

4811
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &pStream), code, lino, _exit, terrno);
9,132✔
4812
  }
4813

4814
  return true;
8,147✔
4815

4816
_exit:
×
4817

4818
  if (code) {
×
4819
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4820
  }  
4821

4822
  *(int32_t*)p3 = code;
×
4823

4824
  return false;
×
4825
}
4826

4827

4828
int32_t msmCheckSnodeReassign(SMnode *pMnode, SSnodeObj* pSnode, SArray** ppRes) {
42,065✔
4829
  int32_t code = TSDB_CODE_SUCCESS;
42,065✔
4830
  int32_t lino = 0;
42,065✔
4831
  
4832
  sdbTraverse(pMnode->pSdb, SDB_STREAM, msmCheckStreamAssign, pSnode, ppRes, &code);
42,065✔
4833
  TAOS_CHECK_EXIT(code);
42,065✔
4834

4835
  int32_t streamNum = taosArrayGetSize(*ppRes);
42,065✔
4836
  if (streamNum > 0 && 0 == pSnode->replicaId) {
42,065✔
4837
    mstError("snode %d has no replica while %d streams assigned", pSnode->id, streamNum);
208✔
4838
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_SNODE_IN_USE);
208✔
4839
  }
4840

4841
  //STREAMTODO CHECK REPLICA UPDATED OR NOT
4842

4843
_exit:
42,065✔
4844

4845
  if (code) {
42,065✔
4846
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
208✔
4847
  }  
4848

4849
  return code;
42,065✔
4850
}
4851

4852
static bool msmCheckLoopStreamSdb(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
662,645✔
4853
  SStreamObj* pStream = pObj;
662,645✔
4854
  int64_t streamId = pStream->pCreate->streamId;
662,645✔
4855
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
662,645✔
4856
  SStmCheckStatusCtx* pCtx = (SStmCheckStatusCtx*)p1;
662,645✔
4857
  int8_t userDropped = atomic_load_8(&pStream->userDropped), userStopped = atomic_load_8(&pStream->userStopped);
662,645✔
4858
  
4859
  if ((userDropped || userStopped) && (NULL == pStatus)) {
662,645✔
4860
    mstsDebug("stream userDropped %d userStopped %d and not in streamMap, ignore it", userDropped, userStopped);
208✔
4861
    return true;
208✔
4862
  }
4863
  
4864
  if (pStatus && !MST_STM_PASS_ISOLATION(pStream, pStatus)) {
662,437✔
4865
    mstsDebug("stream not pass isolation time, updateTime:%" PRId64 ", lastActionTs:%" PRId64 ", currentTs %" PRId64 ", ignore check it", 
583,862✔
4866
        pStream->updateTime, pStatus->lastActionTs, mStreamMgmt.hCtx.currentTs);
4867
    return true;
583,862✔
4868
  }
4869

4870
  if (NULL == pStatus && !MST_STM_STATIC_PASS_SHORT_ISOLATION(pStream)) {
78,575✔
4871
    mstsDebug("stream not pass static isolation time, updateTime:%" PRId64 ", currentTs %" PRId64 ", ignore check it", 
50,106✔
4872
        pStream->updateTime, mStreamMgmt.hCtx.currentTs);
4873
    return true;
50,106✔
4874
  }  
4875

4876
  if (pStatus) {
28,469✔
4877
    if (userDropped || userStopped || MST_IS_USER_STOPPED(atomic_load_8(&pStatus->stopped))) {
27,235✔
4878
      (void)msmRemoveStreamFromMaps(pMnode, streamId);
×
4879
    }
4880

4881
    return true;
27,235✔
4882
  }
4883

4884
  mstPostStreamAction(mStreamMgmt.actionQ, streamId, pStream->pCreate->name, NULL, false, STREAM_ACT_DEPLOY);
1,234✔
4885

4886
  return true;
1,234✔
4887
}
4888

4889
void msmCheckLoopStreamMap(SMnode *pMnode) {
51,368✔
4890
  SStmStatus* pStatus = NULL;
51,368✔
4891
  void* pIter = NULL;
51,368✔
4892
  int8_t stopped = 0;
51,368✔
4893
  int64_t streamId = 0;
51,368✔
4894
  
4895
  while (true) {
4896
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
324,336✔
4897
    if (NULL == pIter) {
324,336✔
4898
      break;
51,368✔
4899
    }
4900

4901
    pStatus = (SStmStatus*)pIter;
272,968✔
4902

4903
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
272,968✔
4904
    stopped = atomic_load_8(&pStatus->stopped);
272,968✔
4905
    if (MST_IS_USER_STOPPED(stopped)) {
272,968✔
4906
      mstsDebug("stream already stopped by user, deployTimes:%" PRId64, pStatus->deployTimes);
444✔
4907
      (void)msmRemoveStreamFromMaps(pMnode, streamId);
444✔
4908
      continue;
444✔
4909
    }
4910

4911
    if (!sdbCheckExists(pMnode->pSdb, SDB_STREAM, pStatus->streamName)) {
272,524✔
4912
      mstsDebug("stream already not exists, deployTimes:%" PRId64, pStatus->deployTimes);
×
4913
      (void)msmRemoveStreamFromMaps(pMnode, *(int64_t*)taosHashGetKey(pIter, NULL));
×
4914
      continue;
×
4915
    }
4916

4917
    if (MST_IS_ERROR_STOPPED(stopped)) {
272,524✔
4918
      if (mStreamMgmt.hCtx.currentTs < pStatus->fatalRetryTs) {
18,169✔
4919
        mstsDebug("stream already stopped by error %s, retried times:%" PRId64 ", next time not reached, currTs:%" PRId64 ", nextRetryTs:%" PRId64,
12,187✔
4920
            tstrerror(pStatus->fatalError), pStatus->fatalRetryTimes, mStreamMgmt.hCtx.currentTs, pStatus->fatalRetryTs);
4921
            
4922
        MND_STREAM_SET_LAST_TS(STM_EVENT_STM_TERR, mStreamMgmt.hCtx.currentTs);
12,187✔
4923
        continue;
12,187✔
4924
      }
4925

4926
      mstPostStreamAction(mStreamMgmt.actionQ, *(int64_t*)taosHashGetKey(pIter, NULL), pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
5,982✔
4927
      continue;
5,982✔
4928
    }
4929

4930
    if (MST_IS_GRANT_STOPPED(stopped) && TSDB_CODE_SUCCESS == grantCheckExpire(TSDB_GRANT_STREAMS)) {
254,355✔
4931
      mstPostStreamAction(mStreamMgmt.actionQ, *(int64_t*)taosHashGetKey(pIter, NULL), pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
×
4932
      continue;
×
4933
    }
4934
  }
4935
}
51,368✔
4936

4937
void msmCheckStreamsStatus(SMnode *pMnode) {
432,487✔
4938
  SStmCheckStatusCtx ctx = {0};
432,487✔
4939

4940
  mstDebug("start to check streams status, currTs:%" PRId64, mStreamMgmt.hCtx.currentTs);
432,487✔
4941
  
4942
  if (MST_READY_FOR_SDB_LOOP()) {
432,487✔
4943
    mstDebug("ready to check sdb loop, lastLoopSdbTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_SDB].ts);
106,607✔
4944
    sdbTraverse(pMnode->pSdb, SDB_STREAM, msmCheckLoopStreamSdb, &ctx, NULL, NULL);
106,607✔
4945
    MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_SDB, mStreamMgmt.hCtx.currentTs);
106,607✔
4946
  }
4947

4948
  if (MST_READY_FOR_MAP_LOOP()) {
432,487✔
4949
    mstDebug("ready to check map loop, lastLoopMapTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_MAP].ts);
51,368✔
4950
    msmCheckLoopStreamMap(pMnode);
51,368✔
4951
    MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_MAP, mStreamMgmt.hCtx.currentTs);
51,368✔
4952
  }
4953
}
432,487✔
4954

4955
void msmCheckTaskListStatus(int64_t streamId, SStmTaskStatus** pList, int32_t taskNum) {
5,377,623✔
4956
  for (int32_t i = 0; i < taskNum; ++i) {
11,336,195✔
4957
    SStmTaskStatus* pTask = *(pList + i);
5,958,572✔
4958

4959
    if (atomic_load_8(&((SStmStatus*)pTask->pStream)->stopped)) {
5,958,572✔
4960
      continue;
579,465✔
4961
    }
4962
    
4963
    if (!MST_PASS_ISOLATION(pTask->lastUpTs, 1)) {
5,381,347✔
4964
      continue;
5,380,005✔
4965
    }
4966

4967
    int64_t noUpTs = mStreamMgmt.hCtx.currentTs - pTask->lastUpTs;
1,342✔
4968
    if (STREAM_RUNNER_TASK == pTask->type || STREAM_TRIGGER_TASK == pTask->type) {
1,342✔
4969
      mstsWarn("%s TASK:%" PRIx64 " status not updated for %" PRId64 "ms, will try to redeploy it", 
×
4970
          gStreamTaskTypeStr[pTask->type], pTask->id.taskId, noUpTs);
4971
          
4972
      msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_TASK_LOST, mStreamMgmt.hCtx.currentTs);
×
4973
      break;
×
4974
    }
4975

4976
    mstsInfo("%s TASK:%" PRIx64 " status not updated for %" PRId64 "ms, will try to redeploy it", 
1,342✔
4977
        gStreamTaskTypeStr[pTask->type], pTask->id.taskId, noUpTs);
4978

4979
    int64_t newSid = atomic_add_fetch_64(&pTask->id.seriousId, 1);
1,342✔
4980
    mstsDebug("task %" PRIx64 " SID updated to %" PRIx64, pTask->id.taskId, newSid);
1,342✔
4981

4982
    SStmTaskAction task = {0};
1,342✔
4983
    task.streamId = streamId;
1,342✔
4984
    task.id = pTask->id;
1,342✔
4985
    task.flag = pTask->flags;
1,342✔
4986
    task.type = pTask->type;
1,342✔
4987
    
4988
    mstPostTaskAction(mStreamMgmt.actionQ, &task, STREAM_ACT_DEPLOY);
1,342✔
4989
  }
4990
}
5,377,623✔
4991

4992
void msmCheckVgroupStreamStatus(SHashObj* pStreams) {
178,820✔
4993
  void* pIter = NULL;
178,820✔
4994
  SStmVgStreamStatus* pVg = NULL;
178,820✔
4995
  int64_t streamId = 0;
178,820✔
4996
  
4997
  while (true) {
2,192,301✔
4998
    pIter = taosHashIterate(pStreams, pIter);
2,371,121✔
4999
    if (NULL == pIter) {
2,371,121✔
5000
      break;
178,820✔
5001
    }
5002

5003
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
2,192,301✔
5004
    pVg = (SStmVgStreamStatus*)pIter;
2,192,301✔
5005

5006
    int32_t taskNum = taosArrayGetSize(pVg->trigReaders);
2,192,301✔
5007
    if (taskNum > 0) {
2,192,301✔
5008
      msmCheckTaskListStatus(streamId, taosArrayGet(pVg->trigReaders, 0), taskNum);
1,276,545✔
5009
    }
5010

5011
    taskNum = taosArrayGetSize(pVg->calcReaders);
2,192,301✔
5012
    if (taskNum > 0) {
2,192,301✔
5013
      msmCheckTaskListStatus(streamId, taosArrayGet(pVg->calcReaders, 0), taskNum);
1,474,148✔
5014
    }
5015
  }
5016
}
178,820✔
5017

5018
void msmHandleVgroupLost(SMnode *pMnode, int32_t vgId, SStmVgroupStatus* pVg) {
×
5019
  int64_t streamId = 0;
×
5020
  void* pIter = NULL;
×
5021
  SStmVgStreamStatus* pStream = NULL;
×
5022

5023
  if (!MST_PASS_ISOLATION(pVg->lastUpTs, 5)) {
×
5024
    mstDebug("vgroup %d lost and still in watch time, lastUpTs:%" PRId64 ", streamNum:%d", vgId, pVg->lastUpTs, (int32_t)taosHashGetSize(pVg->streamTasks));
×
5025
    return;
×
5026
  }
5027

5028
  
5029
  while (true) {
5030
    pIter = taosHashIterate(pVg->streamTasks, pIter);
×
5031
    if (NULL == pIter) {
×
5032
      break;
×
5033
    }
5034

5035
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
5036
    
5037
    msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_VGROUP_LOST, mStreamMgmt.hCtx.currentTs);
×
5038
  }
5039

5040
  taosHashClear(pVg->streamTasks);
×
5041
}
5042

5043

5044
void msmCheckVgroupStatus(SMnode *pMnode) {
432,487✔
5045
  void* pIter = NULL;
432,487✔
5046
  int32_t code = 0;
432,487✔
5047
  
5048
  while (true) {
1,679,314✔
5049
    pIter = taosHashIterate(mStreamMgmt.vgroupMap, pIter);
2,111,801✔
5050
    if (NULL == pIter) {
2,111,801✔
5051
      break;
432,487✔
5052
    }
5053

5054
    int32_t vgId = *(int32_t*)taosHashGetKey(pIter, NULL);
1,679,314✔
5055
    if ((vgId % MND_STREAM_ISOLATION_PERIOD_NUM) != mStreamMgmt.hCtx.slotIdx) {
1,679,314✔
5056
      continue;
1,495,466✔
5057
    }
5058
    
5059
    SStmVgroupStatus* pVg = (SStmVgroupStatus*)pIter;
183,848✔
5060

5061
    if (MST_PASS_ISOLATION(pVg->lastUpTs, 1)) {
183,848✔
5062
      SVgObj *pVgroup = mndAcquireVgroup(pMnode, vgId);
5,028✔
5063
      if (NULL == pVgroup) {
5,028✔
5064
        mstDebug("vgroup %d no longer exits, will remove all %d tasks in it", vgId, (int32_t)taosHashGetSize(pVg->streamTasks));
5,028✔
5065
        code = taosHashRemove(mStreamMgmt.vgroupMap, &vgId, sizeof(vgId));
5,028✔
5066
        if (code) {
5,028✔
5067
          mstWarn("remove vgroup %d from vgroupMap failed since %s", vgId, tstrerror(code));
×
5068
        }
5069
        continue;
5,028✔
5070
      }
5071
      mndReleaseVgroup(pMnode, pVgroup);
×
5072
      
5073
      mstWarn("vgroup %d lost, lastUpTs:%" PRId64 ", streamNum:%d", vgId, pVg->lastUpTs, (int32_t)taosHashGetSize(pVg->streamTasks));
×
5074
      
5075
      msmHandleVgroupLost(pMnode, vgId, pVg);
×
5076
      continue;
×
5077
    }
5078

5079
    mstDebug("vgroup %d online, try to check tasks status, currTs:%" PRId64 ", lastUpTs:%" PRId64, vgId, mStreamMgmt.hCtx.currentTs, pVg->lastUpTs);
178,820✔
5080

5081
    msmCheckVgroupStreamStatus(pVg->streamTasks);
178,820✔
5082
  }
5083
}
432,487✔
5084

5085
void msmHandleRunnerRedeploy(int64_t streamId, SStmSnodeStreamStatus* pStream, int32_t* deployNum, int32_t* deployId) {
567✔
5086
  *deployNum = 0;
567✔
5087
  
5088
  for (int32_t i = 0; i < MND_STREAM_RUNNER_DEPLOY_NUM; ++i) {
2,079✔
5089
    if (pStream->runners[i]) {
1,701✔
5090
      int32_t taskNum = taosArrayGetSize(pStream->runners[i]);
567✔
5091
      for (int32_t t = 0; t < taskNum; ++t) {
945✔
5092
        SStmTaskStatus* pTask = taosArrayGetP(pStream->runners[i], t);
567✔
5093
        int8_t stopped = atomic_load_8(&((SStmStatus*)pTask->pStream)->stopped);
567✔
5094
        if (stopped) {
567✔
5095
          mstsDebug("stream already stopped %d, ignore it", stopped);
189✔
5096
          *deployNum = 0;
189✔
5097
          return;
189✔
5098
        }
5099

5100
        int64_t newSid = atomic_add_fetch_64(&pTask->id.seriousId, 1);
378✔
5101
        mstsDebug("task %" PRIx64 " SID updated to %" PRIx64, pTask->id.taskId, newSid);
378✔
5102
      }
5103
      
5104
      deployId[*deployNum] = i;
378✔
5105
      (*deployNum)++;
378✔
5106
    }
5107
  }
5108
}
5109

5110
void msmHandleSnodeLost(SMnode *pMnode, SStmSnodeStatus* pSnode) {
1,323✔
5111
  pSnode->runnerThreadNum = -1;
1,323✔
5112

5113
  (void)msmSTAddSnodesToMap(pMnode);
1,323✔
5114

5115
  int64_t streamId = 0;
1,323✔
5116
  void* pIter = NULL;
1,323✔
5117
  SStmSnodeStreamStatus* pStream = NULL;
1,323✔
5118
  int32_t deployNum = 0;
1,323✔
5119
  SStmTaskAction task = {0};
1,323✔
5120
  
5121
  while (true) {
5122
    pIter = taosHashIterate(pSnode->streamTasks, pIter);
2,268✔
5123
    if (NULL == pIter) {
2,268✔
5124
      break;
1,323✔
5125
    }
5126

5127
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
945✔
5128
    
5129
    task.streamId = streamId;
945✔
5130
    
5131
    pStream = (SStmSnodeStreamStatus*)pIter;
945✔
5132
    if (pStream->trigger) {
945✔
5133
      int8_t stopped = atomic_load_8(&((SStmStatus*)pStream->trigger->pStream)->stopped);
378✔
5134
      if (stopped) {
378✔
UNCOV
5135
        mstsDebug("stream already stopped %d, ignore it", stopped);
×
UNCOV
5136
        continue;
×
5137
      }
5138

5139
      mstsInfo("snode lost with trigger task %" PRIx64 ", will try to restart current stream", pStream->trigger->id.taskId);
378✔
5140
      
5141
      msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_SNODE_LOST, mStreamMgmt.hCtx.currentTs);
378✔
5142
    } else {
5143
      msmHandleRunnerRedeploy(streamId, pStream, &task.deployNum, task.deployId);
567✔
5144
      
5145
      if (task.deployNum > 0) {
567✔
5146
        //task.triggerStatus = pStream->trigger;
5147
        task.multiRunner = true;
378✔
5148
        task.type = STREAM_RUNNER_TASK;
378✔
5149
        
5150
        mstPostTaskAction(mStreamMgmt.actionQ, &task, STREAM_ACT_DEPLOY);
378✔
5151
        
5152
        mstsInfo("runner tasks %d redeploys added to actionQ", task.deployNum);
378✔
5153
      }
5154
    }
5155
  }
5156

5157
  taosHashClear(pSnode->streamTasks);
1,323✔
5158
}
1,323✔
5159

5160

5161
void msmCheckSnodeStreamStatus(SHashObj* pStreams) {
50,432✔
5162
  void* pIter = NULL;
50,432✔
5163
  SStmSnodeStreamStatus* pSnode = NULL;
50,432✔
5164
  int64_t streamId = 0;
50,432✔
5165
  
5166
  while (true) {
5167
    pIter = taosHashIterate(pStreams, pIter);
739,225✔
5168
    if (NULL == pIter) {
739,225✔
5169
      break;
50,432✔
5170
    }
5171

5172
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
688,793✔
5173
    pSnode = (SStmSnodeStreamStatus*)pIter;
688,793✔
5174

5175
    if (NULL != pSnode->trigger) {
688,793✔
5176
      msmCheckTaskListStatus(streamId, &pSnode->trigger, 1);
675,966✔
5177
    }
5178

5179
    for (int32_t i = 0; i < MND_STREAM_RUNNER_DEPLOY_NUM; ++i) {
2,755,172✔
5180
      int32_t taskNum = taosArrayGetSize(pSnode->runners[i]);
2,066,379✔
5181
      if (taskNum > 0) {
2,066,379✔
5182
        msmCheckTaskListStatus(streamId, taosArrayGet(pSnode->runners[i], 0), taskNum);
1,950,964✔
5183
      }
5184
    }
5185
  }
5186
}
50,432✔
5187

5188

5189
void msmCheckSnodeStatus(SMnode *pMnode) {
432,487✔
5190
  void* pIter = NULL;
432,487✔
5191
  
5192
  while (true) {
531,619✔
5193
    pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter);
964,106✔
5194
    if (NULL == pIter) {
964,106✔
5195
      break;
432,487✔
5196
    }
5197

5198
    int32_t snodeId = *(int32_t*)taosHashGetKey(pIter, NULL);
531,619✔
5199
    if ((snodeId % MND_STREAM_ISOLATION_PERIOD_NUM) != mStreamMgmt.hCtx.slotIdx) {
531,619✔
5200
      continue;
468,152✔
5201
    }
5202

5203
    mstDebug("start to check snode %d status, currTs:%" PRId64, snodeId, mStreamMgmt.hCtx.currentTs);
63,467✔
5204
    
5205
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
63,467✔
5206
    if (NULL == pSnode->streamTasks) {
63,467✔
5207
      mstDebug("ignore snode %d health check since empty tasks", snodeId);
11,901✔
5208
      continue;
11,901✔
5209
    }
5210
    
5211
    if (MST_PASS_ISOLATION(pSnode->lastUpTs, 1)) {
51,566✔
5212
      mstInfo("snode %d lost, lastUpTs:%" PRId64 ", runnerThreadNum:%d, streamNum:%d", 
1,134✔
5213
          snodeId, pSnode->lastUpTs, pSnode->runnerThreadNum, (int32_t)taosHashGetSize(pSnode->streamTasks));
5214
      
5215
      msmHandleSnodeLost(pMnode, pSnode);
1,134✔
5216
      continue;
1,134✔
5217
    }
5218
    
5219
    mstDebug("snode %d online, try to check tasks status, currTs:%" PRId64 ", lastUpTs:%" PRId64, snodeId, mStreamMgmt.hCtx.currentTs, pSnode->lastUpTs);
50,432✔
5220

5221
    msmCheckSnodeStreamStatus(pSnode->streamTasks);
50,432✔
5222
  }
5223
}
432,487✔
5224

5225

5226
void msmCheckTasksStatus(SMnode *pMnode) {
432,487✔
5227
  mstDebug("start to check tasks status, currTs:%" PRId64, mStreamMgmt.hCtx.currentTs);
432,487✔
5228

5229
  msmCheckVgroupStatus(pMnode);
432,487✔
5230
  msmCheckSnodeStatus(pMnode);
432,487✔
5231
}
432,487✔
5232

5233
void msmCheckSnodesState(SMnode *pMnode) {
432,487✔
5234
  if (!MST_READY_FOR_SNODE_LOOP()) {
432,487✔
5235
    return;
386,648✔
5236
  }
5237

5238
  mstDebug("ready to check snode loop, lastTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_SNODE].ts);
45,839✔
5239

5240
  void* pIter = NULL;
45,839✔
5241
  int32_t snodeId = 0;
45,839✔
5242
  while (true) {
51,047✔
5243
    pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter);
96,886✔
5244
    if (NULL == pIter) {
96,886✔
5245
      break;
45,839✔
5246
    }
5247

5248
    snodeId = *(int32_t*)taosHashGetKey(pIter, NULL);
51,047✔
5249
    if (sdbCheckExists(pMnode->pSdb, SDB_SNODE, &snodeId)) {
51,047✔
5250
      continue;
50,858✔
5251
    }
5252

5253
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
189✔
5254
    if (NULL == pSnode->streamTasks) {
189✔
5255
      mstDebug("snode %d already cleanup, try to rm it", snodeId);
×
5256
      TAOS_UNUSED(taosHashRemove(mStreamMgmt.snodeMap, &snodeId, sizeof(snodeId)));
×
5257
      continue;
×
5258
    }
5259
    
5260
    mstWarn("snode %d lost while streams remain, will redeploy all and rm it, lastUpTs:%" PRId64 ", runnerThreadNum:%d, streamNum:%d", 
189✔
5261
        snodeId, pSnode->lastUpTs, pSnode->runnerThreadNum, (int32_t)taosHashGetSize(pSnode->streamTasks));
5262
    
5263
    msmHandleSnodeLost(pMnode, pSnode);
189✔
5264
  }
5265

5266
  MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_MAP, mStreamMgmt.hCtx.currentTs);
45,839✔
5267
}
5268

5269
bool msmCheckNeedHealthCheck(SMnode *pMnode) {
11,278,538✔
5270
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
11,278,538✔
5271
  if (0 == active || MND_STM_STATE_NORMAL != state) {
11,278,538✔
5272
    mstTrace("ignore health check since active:%d state:%d", active, state);
2,457✔
5273
    return false;
2,457✔
5274
  }
5275

5276
  if (sdbGetSize(pMnode->pSdb, SDB_STREAM) <= 0) {
11,276,081✔
5277
    mstTrace("ignore health check since no stream now");
10,411,107✔
5278
    return false;
10,411,107✔
5279
  }
5280

5281
  return true;
864,974✔
5282
}
5283

5284
void msmHealthCheck(SMnode *pMnode) {
10,846,051✔
5285
  if (!msmCheckNeedHealthCheck(pMnode)) {
10,846,051✔
5286
    return;
10,413,564✔
5287
  }
5288

5289
  mstDebug("start wait health check, currentTs:%" PRId64,  taosGetTimestampMs());
848,434✔
5290
  
5291
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, false);
432,487✔
5292
  if (!msmCheckNeedHealthCheck(pMnode)) {
432,487✔
5293
    taosWUnLockLatch(&mStreamMgmt.runtimeLock);
×
5294
    return;
×
5295
  }
5296
  
5297
  mStreamMgmt.hCtx.slotIdx = (mStreamMgmt.hCtx.slotIdx + 1) % MND_STREAM_ISOLATION_PERIOD_NUM;
432,487✔
5298
  mStreamMgmt.hCtx.currentTs = taosGetTimestampMs();
432,487✔
5299

5300
  mstDebug("start health check, soltIdx:%d, checkStartTs:%" PRId64, mStreamMgmt.hCtx.slotIdx, mStreamMgmt.hCtx.currentTs);
432,487✔
5301
  
5302
  msmCheckStreamsStatus(pMnode);
432,487✔
5303
  msmCheckTasksStatus(pMnode);
432,487✔
5304
  msmCheckSnodesState(pMnode);
432,487✔
5305

5306
  taosWUnLockLatch(&mStreamMgmt.runtimeLock);
432,487✔
5307

5308
  mstDebug("end health check, soltIdx:%d, checkStartTs:%" PRId64, mStreamMgmt.hCtx.slotIdx, mStreamMgmt.hCtx.currentTs);
432,487✔
5309
}
5310

5311
static bool msmUpdateProfileStreams(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
874✔
5312
  SStreamObj *pStream = pObj;
874✔
5313
  if (atomic_load_8(&pStream->userDropped) || atomic_load_8(&pStream->userStopped)) {
874✔
5314
    return true;
×
5315
  }
5316
  
5317
  pStream->updateTime = *(int64_t*)p1;
874✔
5318
  
5319
  (*(int32_t*)p2)++;
874✔
5320
  
5321
  return true;
874✔
5322
}
5323

5324
int32_t msmGetTriggerTaskAddr(SMnode *pMnode, int64_t streamId, SStreamTaskAddr* pAddr) {
21,961✔
5325
  int32_t code = 0;
21,961✔
5326
  int8_t  stopped = 0;
21,961✔
5327
  
5328
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, true);
21,961✔
5329
  
5330
  SStmStatus* pStatus = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
21,961✔
5331
  if (NULL == pStatus) {
21,961✔
5332
    mstsError("stream not exists in streamMap, streamRemains:%d", taosHashGetSize(mStreamMgmt.streamMap));
3,485✔
5333
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
3,485✔
5334
    goto _exit;
3,485✔
5335
  }
5336

5337
  stopped = atomic_load_8(&pStatus->stopped);
18,476✔
5338
  if (stopped) {
18,476✔
5339
    mstsError("stream already stopped, stopped:%d", stopped);
×
5340
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
5341
    goto _exit;
×
5342
  }
5343

5344
  if (pStatus->triggerTask && STREAM_STATUS_RUNNING == pStatus->triggerTask->status) {
18,476✔
5345
    pAddr->taskId = pStatus->triggerTask->id.taskId;
14,756✔
5346
    pAddr->nodeId = pStatus->triggerTask->id.nodeId;
14,756✔
5347
    pAddr->epset = mndGetDnodeEpsetById(pMnode, pAddr->nodeId);
14,756✔
5348
    mstsDebug("stream trigger task %" PRIx64 " got with nodeId %d", pAddr->taskId, pAddr->nodeId);
14,756✔
5349
    goto _exit;
14,756✔
5350
  }
5351

5352
  mstsError("trigger task %p not running, status:%s", pStatus->triggerTask, pStatus->triggerTask ? gStreamStatusStr[pStatus->triggerTask->status] : "unknown");
3,720✔
5353
  code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
3,720✔
5354

5355
_exit:
21,961✔
5356
  
5357
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
21,961✔
5358

5359
  return code;
21,961✔
5360
}
5361

5362
int32_t msmInitRuntimeInfo(SMnode *pMnode) {
433,607✔
5363
  int32_t code = TSDB_CODE_SUCCESS;
433,607✔
5364
  int32_t lino = 0;
433,607✔
5365
  int32_t vnodeNum = sdbGetSize(pMnode->pSdb, SDB_VGROUP);
433,607✔
5366
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
433,607✔
5367
  int32_t dnodeNum = sdbGetSize(pMnode->pSdb, SDB_DNODE);
433,607✔
5368

5369
  MND_STREAM_SET_LAST_TS(STM_EVENT_ACTIVE_BEGIN, taosGetTimestampMs());
866,238✔
5370

5371
  mStreamMgmt.stat.activeTimes++;
433,607✔
5372
  mStreamMgmt.threadNum = tsNumOfMnodeStreamMgmtThreads;
433,607✔
5373
  mStreamMgmt.tCtx = taosMemoryCalloc(mStreamMgmt.threadNum, sizeof(SStmThreadCtx));
433,607✔
5374
  if (NULL == mStreamMgmt.tCtx) {
433,607✔
5375
    code = terrno;
×
5376
    mstError("failed to initialize the stream runtime tCtx, threadNum:%d, error:%s", mStreamMgmt.threadNum, tstrerror(code));
×
5377
    goto _exit;
×
5378
  }
5379

5380
  mStreamMgmt.actionQ = taosMemoryCalloc(1, sizeof(SStmActionQ));
433,607✔
5381
  if (mStreamMgmt.actionQ == NULL) {
433,607✔
5382
    code = terrno;
×
5383
    mError("failed to initialize the stream runtime actionQ, error:%s", tstrerror(code));
×
5384
    goto _exit;
×
5385
  }
5386
  
5387
  mStreamMgmt.actionQ->head = taosMemoryCalloc(1, sizeof(SStmQNode));
433,607✔
5388
  TSDB_CHECK_NULL(mStreamMgmt.actionQ->head, code, lino, _exit, terrno);
433,607✔
5389
  
5390
  mStreamMgmt.actionQ->tail = mStreamMgmt.actionQ->head;
433,607✔
5391
  
5392
  for (int32_t i = 0; i < mStreamMgmt.threadNum; ++i) {
2,599,058✔
5393
    SStmThreadCtx* pCtx = mStreamMgmt.tCtx + i;
2,165,451✔
5394

5395
    for (int32_t m = 0; m < STREAM_MAX_GROUP_NUM; ++m) {
12,992,706✔
5396
      pCtx->deployStm[m] = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
10,827,255✔
5397
      if (pCtx->deployStm[m] == NULL) {
10,827,255✔
5398
        code = terrno;
×
5399
        mError("failed to initialize the stream runtime deployStm[%d][%d], error:%s", i, m, tstrerror(code));
×
5400
        goto _exit;
×
5401
      }
5402
      taosHashSetFreeFp(pCtx->deployStm[m], tDeepFreeSStmStreamDeploy);
10,827,255✔
5403
      
5404
      pCtx->actionStm[m] = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
10,827,255✔
5405
      if (pCtx->actionStm[m] == NULL) {
10,827,255✔
5406
        code = terrno;
×
5407
        mError("failed to initialize the stream runtime actionStm[%d][%d], error:%s", i, m, tstrerror(code));
×
5408
        goto _exit;
×
5409
      }
5410
      taosHashSetFreeFp(pCtx->actionStm[m], mstDestroySStmAction);
10,827,255✔
5411
    }
5412
  }
5413
  
5414
  mStreamMgmt.streamMap = taosHashInit(MND_STREAM_DEFAULT_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
433,607✔
5415
  if (mStreamMgmt.streamMap == NULL) {
433,607✔
5416
    code = terrno;
×
5417
    mError("failed to initialize the stream runtime streamMap, error:%s", tstrerror(code));
×
5418
    goto _exit;
×
5419
  }
5420
  taosHashSetFreeFp(mStreamMgmt.streamMap, mstDestroySStmStatus);
433,607✔
5421
  
5422
  mStreamMgmt.taskMap = taosHashInit(MND_STREAM_DEFAULT_TASK_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
433,607✔
5423
  if (mStreamMgmt.taskMap == NULL) {
433,607✔
5424
    code = terrno;
×
5425
    mError("failed to initialize the stream runtime taskMap, error:%s", tstrerror(code));
×
5426
    goto _exit;
×
5427
  }
5428
  
5429
  mStreamMgmt.vgroupMap = taosHashInit(vnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
433,607✔
5430
  if (mStreamMgmt.vgroupMap == NULL) {
433,607✔
5431
    code = terrno;
×
5432
    mError("failed to initialize the stream runtime vgroupMap, error:%s", tstrerror(code));
×
5433
    goto _exit;
×
5434
  }
5435
  taosHashSetFreeFp(mStreamMgmt.vgroupMap, mstDestroySStmVgroupStatus);
433,607✔
5436

5437
  mStreamMgmt.snodeMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
433,607✔
5438
  if (mStreamMgmt.snodeMap == NULL) {
433,607✔
5439
    code = terrno;
×
5440
    mError("failed to initialize the stream runtime snodeMap, error:%s", tstrerror(code));
×
5441
    goto _exit;
×
5442
  }
5443
  taosHashSetFreeFp(mStreamMgmt.snodeMap, mstDestroySStmSnodeStatus);
433,607✔
5444
  
5445
  mStreamMgmt.dnodeMap = taosHashInit(dnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
433,607✔
5446
  if (mStreamMgmt.dnodeMap == NULL) {
433,607✔
5447
    code = terrno;
×
5448
    mError("failed to initialize the stream runtime dnodeMap, error:%s", tstrerror(code));
×
5449
    goto _exit;
×
5450
  }
5451

5452
  mStreamMgmt.toDeployVgMap = taosHashInit(vnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
433,607✔
5453
  if (mStreamMgmt.toDeployVgMap == NULL) {
433,607✔
5454
    code = terrno;
×
5455
    mError("failed to initialize the stream runtime toDeployVgMap, error:%s", tstrerror(code));
×
5456
    goto _exit;
×
5457
  }
5458
  taosHashSetFreeFp(mStreamMgmt.toDeployVgMap, mstDestroySStmVgTasksToDeploy);
433,607✔
5459
  
5460
  mStreamMgmt.toDeploySnodeMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
433,607✔
5461
  if (mStreamMgmt.toDeploySnodeMap == NULL) {
433,607✔
5462
    code = terrno;
×
5463
    mError("failed to initialize the stream runtime toDeploySnodeMap, error:%s", tstrerror(code));
×
5464
    goto _exit;
×
5465
  }
5466
  taosHashSetFreeFp(mStreamMgmt.toDeploySnodeMap, mstDestroySStmSnodeTasksDeploy);
433,607✔
5467

5468
  mStreamMgmt.toUpdateScanMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
433,607✔
5469
  if (mStreamMgmt.toUpdateScanMap == NULL) {
433,607✔
5470
    code = terrno;
×
5471
    mError("failed to initialize the stream runtime toUpdateScanMap, error:%s", tstrerror(code));
×
5472
    goto _exit;
×
5473
  }
5474
  taosHashSetFreeFp(mStreamMgmt.toUpdateScanMap, mstDestroyScanAddrList);
433,607✔
5475

5476
  TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pMnode));
433,607✔
5477
  TAOS_CHECK_EXIT(msmSTAddDnodesToMap(pMnode));
433,607✔
5478

5479
  mStreamMgmt.lastTaskId = 1;
433,607✔
5480

5481
  int32_t activeStreamNum = 0;
433,607✔
5482
  sdbTraverse(pMnode->pSdb, SDB_STREAM, msmUpdateProfileStreams, &MND_STREAM_GET_LAST_TS(STM_EVENT_ACTIVE_BEGIN), &activeStreamNum, NULL);
433,607✔
5483

5484
  if (activeStreamNum > 0) {
433,607✔
5485
    msmSetInitRuntimeState(MND_STM_STATE_WATCH);
700✔
5486
  } else {
5487
    msmSetInitRuntimeState(MND_STM_STATE_NORMAL);
432,907✔
5488
  }
5489

5490
_exit:
433,607✔
5491

5492
  if (code) {
433,607✔
5493
    msmDestroyRuntimeInfo(pMnode);
×
5494
    mstError("%s failed at line %d since %s", __FUNCTION__, lino, tstrerror(code));
×
5495
  } else {
5496
    mstInfo("mnode stream runtime init done");
433,607✔
5497
  }
5498

5499
  return code;
433,607✔
5500
}
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