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

taosdata / TDengine / #4943

30 Jan 2026 06:19AM UTC coverage: 66.718% (-0.07%) from 66.788%
#4943

push

travis-ci

web-flow
merge: from main to 3.0 #34453

1122 of 2018 new or added lines in 72 files covered. (55.6%)

823 existing lines in 156 files now uncovered.

204811 of 306978 relevant lines covered (66.72%)

123993567.34 hits per line

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

72.67
/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() {
737,142✔
34
  SStmQNode* pQNode = NULL;
737,142✔
35

36
  if (NULL == mStreamMgmt.actionQ) {
737,142✔
37
    return;
368,571✔
38
  }
39

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

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

47
void msmDestroySStmThreadCtx(SStmThreadCtx* pCtx) {
1,842,665✔
48
  for (int32_t m = 0; m < STREAM_MAX_GROUP_NUM; ++m) {
11,055,990✔
49
    taosHashCleanup(pCtx->deployStm[m]);
9,213,325✔
50
    taosHashCleanup(pCtx->actionStm[m]);
9,213,325✔
51
  }
52
}
1,842,665✔
53

54
void msmDestroyThreadCtxs() {
737,142✔
55
  if (NULL == mStreamMgmt.tCtx) {
737,142✔
56
    return;
368,571✔
57
  }
58
  
59
  for (int32_t i = 0; i < mStreamMgmt.threadNum; ++i) {
2,211,236✔
60
    msmDestroySStmThreadCtx(mStreamMgmt.tCtx + i);
1,842,665✔
61
  }
62
  taosMemoryFreeClear(mStreamMgmt.tCtx);
368,571✔
63
}
64

65

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

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

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

91
  memset(mStreamMgmt.lastTs, 0, sizeof(mStreamMgmt.lastTs));
737,142✔
92

93
  mstInfo("mnode stream mgmt destroyed");  
737,142✔
94
}
737,142✔
95

96

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

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

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

111
    pStatus = pStream;
513✔
112
  }
113

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

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

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

136
_exit:
432✔
137

138
  taosHashRelease(mStreamMgmt.streamMap, pStream);
4,816✔
139

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

145

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

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

200
  pSnode = NULL;
387,870✔
201

202
_exit:
387,870✔
203

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

208
  return code;
387,870✔
209
}
210

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

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

235
  pDnode = NULL;
846,253✔
236

237
_exit:
846,253✔
238

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

243
  return code;
846,253✔
244
}
245

246

247

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

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

274
static int32_t msmSTAddToVgStreamHash(SHashObj* pHash, int64_t streamId, SStmTaskStatus* pStatus, bool trigReader) {
496,029✔
275
  int32_t code = TSDB_CODE_SUCCESS;
496,029✔
276
  int32_t lino = 0;
496,029✔
277
  SStmVgStreamStatus* pStream = taosHashGet(pHash, &streamId, sizeof(streamId));
496,029✔
278
  if (NULL == pStream) {
496,029✔
279
    SStmVgStreamStatus stream = {0};
370,400✔
280
    if (trigReader) {
370,400✔
281
      stream.trigReaders = taosArrayInit(1, POINTER_BYTES);
230,856✔
282
      TSDB_CHECK_NULL(stream.trigReaders, code, lino, _exit, terrno);
230,856✔
283
      TSDB_CHECK_NULL(taosArrayPush(stream.trigReaders, &pStatus), code, lino, _exit, terrno);
461,712✔
284
    } else {
285
      stream.calcReaders = taosArrayInit(2, POINTER_BYTES);
139,544✔
286
      TSDB_CHECK_NULL(stream.calcReaders, code, lino, _exit, terrno);
139,544✔
287
      TSDB_CHECK_NULL(taosArrayPush(stream.calcReaders, &pStatus), code, lino, _exit, terrno);
279,088✔
288
    }
289
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &stream, sizeof(stream)));
370,400✔
290
    goto _exit;
370,400✔
291
  }
292
  
293
  if (trigReader) {
125,629✔
294
    if (NULL == pStream->trigReaders) {
21,824✔
295
      pStream->trigReaders = taosArrayInit(1, POINTER_BYTES);
21,824✔
296
      TSDB_CHECK_NULL(pStream->trigReaders, code, lino, _exit, terrno);
21,824✔
297
    }
298
    
299
    TSDB_CHECK_NULL(taosArrayPush(pStream->trigReaders, &pStatus), code, lino, _exit, terrno);
43,648✔
300
    goto _exit;
21,824✔
301
  }
302
  
303
  if (NULL == pStream->calcReaders) {
103,805✔
304
    pStream->calcReaders = taosArrayInit(1, POINTER_BYTES);
75,879✔
305
    TSDB_CHECK_NULL(pStream->calcReaders, code, lino, _exit, terrno);
75,879✔
306
  }
307

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

310
_exit:
103,805✔
311

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

320
  return code;
496,029✔
321
}
322

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

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

334
    vg.lastUpTs = taosGetTimestampMs();
59,700✔
335
    TAOS_CHECK_EXIT(msmSTAddToVgStreamHash(vg.streamTasks, streamId, pStatus, trigReader));
59,700✔
336
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.vgroupMap, &pStatus->id.nodeId, sizeof(pStatus->id.nodeId), &vg, sizeof(vg)));
59,700✔
337
  } else {
338
    TAOS_CHECK_EXIT(msmSTAddToVgStreamHash(pVg->streamTasks, streamId, pStatus, trigReader));
436,329✔
339
  }
340
  
341
_exit:
495,921✔
342

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

350
  return code;
496,029✔
351
}
352

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

361
  while (true) {
×
362
    SStmVgTasksToDeploy* pVg = taosHashAcquire(pVgMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId));
497,055✔
363
    if (NULL == pVg) {
497,055✔
364
      vg.taskList = taosArrayInit(20, sizeof(SStmTaskToDeployExt));
89,795✔
365
      TSDB_CHECK_NULL(vg.taskList, code, lino, _return, terrno);
89,795✔
366
      TSDB_CHECK_NULL(taosArrayPush(vg.taskList, &ext), code, lino, _return, terrno);
179,590✔
367
      code = taosHashPut(pVgMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &vg, sizeof(SStmVgTasksToDeploy));
89,795✔
368
      if (TSDB_CODE_SUCCESS == code) {
89,795✔
369
        goto _return;
89,795✔
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);
407,260✔
381
    if (NULL == pVg->taskList) {
407,260✔
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)) {
814,520✔
386
      taosWUnLockLatch(&pVg->lock);
×
387
      TSDB_CHECK_NULL(NULL, code, lino, _return, terrno);
×
388
    }
389
    taosWUnLockLatch(&pVg->lock);
407,260✔
390
    
391
    taosHashRelease(pVgMap, pVg);
407,260✔
392
    break;
407,260✔
393
  }
394
  
395
_return:
497,055✔
396

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

404
  return code;
497,055✔
405
}
406

407

408
static int32_t msmSTAddToSnodeStreamHash(SHashObj* pHash, int64_t streamId, SStmTaskStatus* pStatus, int32_t deployId) {
661,906✔
409
  int32_t code = TSDB_CODE_SUCCESS;
661,906✔
410
  int32_t lino = 0;
661,906✔
411
  SStmSnodeStreamStatus* pStream = taosHashGet(pHash, &streamId, sizeof(streamId));
661,906✔
412
  if (NULL == pStream) {
661,906✔
413
    SStmSnodeStreamStatus stream = {0};
169,087✔
414
    if (deployId < 0) {
169,087✔
415
      stream.trigger = pStatus;
3,120✔
416
    } else {
417
      stream.runners[deployId] = taosArrayInit(2, POINTER_BYTES);
165,967✔
418
      TSDB_CHECK_NULL(stream.runners[deployId], code, lino, _exit, terrno);
165,967✔
419
      TSDB_CHECK_NULL(taosArrayPush(stream.runners[deployId], &pStatus), code, lino, _exit, terrno);
331,934✔
420
    }
421
    
422
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &stream, sizeof(stream)));
169,087✔
423
    goto _exit;
169,087✔
424
  }
425
  
426
  if (deployId < 0) {
492,819✔
427
    if (NULL != pStream->trigger) {
160,012✔
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;
160,012✔
433
    goto _exit;
160,012✔
434
  }
435
  
436
  if (NULL == pStream->runners[deployId]) {
332,807✔
437
    pStream->runners[deployId] = taosArrayInit(2, POINTER_BYTES);
314,069✔
438
    TSDB_CHECK_NULL(pStream->runners[deployId], code, lino, _exit, terrno);
314,069✔
439
  }
440

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

443
_exit:
332,807✔
444

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

453
  return code;
661,906✔
454
}
455

456

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

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

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

484
  return code;
661,906✔
485
}
486

487

488

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

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

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

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

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

550
  return code;
163,132✔
551
}
552

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

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

567
      ext.deploy = *pDeploy;
33,172✔
568
      ext.deployed = false;
33,172✔
569
      TSDB_CHECK_NULL(taosArrayPush(snode.runnerList, &ext), code, lino, _return, terrno);
66,344✔
570

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

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

614
  return code;
498,774✔
615
}
616

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

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

632
_exit:
480,036✔
633

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

638
  return code;
480,036✔
639
}
640

641

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

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

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

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

672
        continue;
×
673
      }
674

675
      return code;
12,167✔
676
    }
677

678
    break;
679
  }
680

UNCOV
681
_exit:
×
682

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

UNCOV
687
  return code;  
×
688
}
689

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

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

707
      continue;
×
708
    }
709

710
    return;
58,235✔
711
  }  
712
}
713

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

719
  mstDebug("start to update vgroups upTs");
17,656,523✔
720
  
721
  for (int32_t i = 0; i < vgNum; ++i) {
72,176,210✔
722
    int32_t* vgId = taosArrayGet(pCtx->pReq->pVgLeaders, i);
54,519,687✔
723

724
    msmUpdateVgroupUpTs(pCtx, *vgId);
54,519,687✔
725
  }
726

727
_exit:
17,656,523✔
728

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

733
  return code;
17,656,523✔
734
}
735

736

737

738
void* msmSearchCalcCacheScanPlan(SArray* pList) {
312,322✔
739
  int32_t num = taosArrayGetSize(pList);
312,322✔
740
  for (int32_t i = 0; i < num; ++i) {
886,254✔
741
    SStreamCalcScan* pScan = taosArrayGet(pList, i);
736,174✔
742
    if (pScan->readFromCache) {
736,174✔
743
      return pScan->scanPlan;
162,242✔
744
    }
745
  }
746

747
  return NULL;
150,080✔
748
}
749

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

774
  return TSDB_CODE_SUCCESS;
497,055✔
775
}
776

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

781
  if (pInfo->runnerDeploys > 0) {
160,012✔
782
    *ppRes = taosArrayInit(pInfo->runnerDeploys, sizeof(SStreamRunnerTarget));
160,012✔
783
    TSDB_CHECK_NULL(*ppRes, code, lino, _exit, terrno);
160,012✔
784
  }
785
  
786
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
640,048✔
787
    SStmTaskStatus* pStatus = taosArrayGetLast(pInfo->runners[i]);
480,036✔
788
    TSDB_CHECK_NULL(pStatus, code, lino, _exit, terrno);
480,036✔
789

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

805
_exit:
160,012✔
806

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

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

826
  mndReleaseSnode(pMnode, pSnode);
×
827

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

833
  return TSDB_CODE_SUCCESS;
×
834
}
835

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

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

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

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

875
  SStreamTaskAddr addr;
162,754✔
876
  int32_t triggerReaderNum = taosArrayGetSize(pInfo->trigReaders);
163,132✔
877
  if (triggerReaderNum > 0) {
163,132✔
878
    pMsg->readerList = taosArrayInit(triggerReaderNum, sizeof(SStreamTaskAddr));
162,190✔
879
    TSDB_CHECK_NULL(pMsg->readerList, code, lino, _exit, terrno);
162,190✔
880
  }
881
  
882
  for (int32_t i = 0; i < triggerReaderNum; ++i) {
358,724✔
883
    SStmTaskStatus* pStatus = taosArrayGet(pInfo->trigReaders, i);
195,592✔
884
    addr.taskId = pStatus->id.taskId;
195,592✔
885
    addr.nodeId = pStatus->id.nodeId;
195,592✔
886
    addr.epset = mndGetVgroupEpsetById(pMnode, pStatus->id.nodeId);
195,592✔
887
    TSDB_CHECK_NULL(taosArrayPush(pMsg->readerList, &addr), code, lino, _exit, terrno);
391,184✔
888
    mstsDebug("the %dth trigReader src added to trigger's readerList, TASK:%" PRIx64 " nodeId:%d", i, addr.taskId, addr.nodeId);
195,592✔
889
  }
890

891
  pMsg->leaderSnodeId = pStream->mainSnodeId;
163,132✔
892
  pMsg->streamName = pInfo->streamName;
163,132✔
893

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

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

901
_exit:
160,012✔
902

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

912

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

920
  pMsg->execReplica = pInfo->runnerReplica;
498,774✔
921
  pMsg->streamName = pInfo->streamName;
498,774✔
922
  //TAOS_CHECK_EXIT(nodesCloneNode((SNode*)plan, (SNode**)&pMsg->pPlan));
923
  pMsg->pPlan = plan;
498,774✔
924
  pMsg->outDBFName = pInfo->pCreate->outDB;
498,774✔
925
  pMsg->outTblName = pInfo->pCreate->outTblName;
498,774✔
926
  pMsg->outTblType = pStream->pCreate->outTblType;
498,774✔
927
  pMsg->lowLatencyCalc = pStream->pCreate->lowLatencyCalc;
498,774✔
928
  pMsg->calcNotifyOnly = pStream->pCreate->calcNotifyOnly;
498,774✔
929
  pMsg->topPlan = topPlan;
498,774✔
930
  pMsg->pNotifyAddrUrls = pInfo->pCreate->pNotifyAddrUrls;
498,774✔
931
  pMsg->addOptions = pStream->pCreate->addOptions;
498,774✔
932
  if ((WINDOW_TYPE_INTERVAL == pStream->pCreate->triggerType && pStream->pCreate->trigger.sliding.overlap) ||
498,774✔
933
      (WINDOW_TYPE_COUNT == pStream->pCreate->triggerType &&
486,714✔
934
       pStream->pCreate->trigger.count.sliding < pStream->pCreate->trigger.count.countVal)) {
32,058✔
935
    pMsg->addOptions |= CALC_SLIDING_OVERLAP;
13,338✔
936
  }
937
  pMsg->outCols = pInfo->pCreate->outCols;
498,774✔
938
  pMsg->outTags = pInfo->pCreate->outTags;
498,774✔
939
  pMsg->outStbUid = pStream->pCreate->outStbUid;
498,774✔
940
  pMsg->outStbSversion = pStream->pCreate->outStbSversion;
498,774✔
941
  
942
  pMsg->subTblNameExpr = pInfo->pCreate->subTblNameExpr;
498,774✔
943
  pMsg->tagValueExpr = pInfo->pCreate->tagValueExpr;
498,774✔
944
  pMsg->forceOutCols = pInfo->pCreate->forceOutCols;
498,774✔
945

946
  pMsg->colCids = pInfo->pCreate->colCids;
498,774✔
947
  pMsg->tagCids = pInfo->pCreate->tagCids;
498,774✔
948
_exit:
498,774✔
949

950
  if (code) {
498,774✔
951
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
952
  }
953
  
954
  return code;
498,774✔
955
}
956

957

958
static int32_t msmSTAddToVgroupMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SList* pList, SStmTaskStatus* pTask, bool trigReader) {
385,651✔
959
  int32_t code = TSDB_CODE_SUCCESS;
385,651✔
960
  int32_t lino = 0;
385,651✔
961
  int32_t taskNum = pTask ? 1 : (pList ? MST_LIST_SIZE(pList) :taosArrayGetSize(pTasks));
385,651✔
962
  SListNode* pNode = pList ? listHead(pList) : NULL;
385,651✔
963
  
964
  for (int32_t i = 0; i < taskNum; ++i) {
881,680✔
965
    SStmTaskStatus* pStatus = pTask ? pTask : (pNode ? (SStmTaskStatus*)pNode->data : taosArrayGet(pTasks, i));
496,029✔
966
    TAOS_CHECK_EXIT(msmSTAddToVgroupMapImpl(streamId, pStatus, trigReader));
496,029✔
967
    if (pNode) {
496,029✔
968
      pNode = TD_DLIST_NODE_NEXT(pNode);
241,050✔
969
    }
970
  }
971
  
972
_exit:
385,651✔
973

974
  if (code) {
385,651✔
975
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
976
  }
977
  
978
  return code;
385,651✔
979
}
980

981

982
static int32_t msmSTAddToSnodeMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SStmTaskStatus* pTask, int32_t taskNum, int32_t deployId) {
643,168✔
983
  int32_t code = TSDB_CODE_SUCCESS;
643,168✔
984
  int32_t lino = 0;
643,168✔
985
  int32_t rtaskNum = (taskNum > 0) ? taskNum : taosArrayGetSize(pTasks);
643,168✔
986
  int32_t taskType = (deployId < 0) ? STREAM_TRIGGER_TASK : STREAM_RUNNER_TASK;
643,168✔
987
  
988
  for (int32_t i = 0; i < rtaskNum; ++i) {
1,305,074✔
989
    SStmTaskStatus* pStatus = (taskNum > 0) ? (pTask + i) : taosArrayGet(pTasks, i);
661,906✔
990
    TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pStatus, deployId));
661,906✔
991
  }
992
  
993
_exit:
643,168✔
994

995
  if (code) {
643,168✔
996
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
997
  }
998

999
  return code;
643,168✔
1000
}
1001

1002
int64_t msmAssignTaskId(void) {
1,157,935✔
1003
  return atomic_fetch_add_64(&mStreamMgmt.lastTaskId, 1);
1,157,935✔
1004
}
1005

1006
int64_t msmAssignTaskSeriousId(void) {
1,157,935✔
1007
  return taosGetTimestampNs();
1,157,935✔
1008
}
1009

1010

1011
int32_t msmIsSnodeAlive(SMnode* pMnode, int32_t snodeId, int64_t streamId, bool* alive) {
828,876✔
1012
  int32_t code = TSDB_CODE_SUCCESS;
828,876✔
1013
  int32_t lino = 0;
828,876✔
1014
  bool     noExists = false;
828,876✔
1015
  SStmSnodeStatus* pStatus = NULL;
828,876✔
1016

1017
  while (true) {
1018
    pStatus = taosHashGet(mStreamMgmt.snodeMap, &snodeId, sizeof(snodeId));
835,153✔
1019
    if (NULL == pStatus) {
835,153✔
1020
      if (noExists) {
6,277✔
1021
        mstsError("snode %d not exists in snodeMap", snodeId);
×
1022
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1023
      }
1024

1025
      noExists = true;
6,277✔
1026
      TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pMnode));
6,277✔
1027
      
1028
      continue;
6,277✔
1029
    }
1030

1031
    *alive = (pStatus->runnerThreadNum >= 0);
828,876✔
1032
    break;
828,876✔
1033
  }
1034

1035
_exit:
828,876✔
1036

1037
  if (code) {
828,876✔
1038
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1039
  }
1040

1041
  return code;
828,876✔
1042
}
1043

1044
int32_t msmRetrieveStaticSnodeId(SMnode* pMnode, SStreamObj* pStream) {
323,144✔
1045
  int32_t code = TSDB_CODE_SUCCESS;
323,144✔
1046
  int32_t lino = 0;
323,144✔
1047
  bool alive = false;
323,144✔
1048
  int32_t mainSnodeId = atomic_load_32(&pStream->mainSnodeId);
323,144✔
1049
  int32_t snodeId = mainSnodeId;
323,144✔
1050
  int64_t streamId = pStream->pCreate->streamId;
323,144✔
1051
  
1052
  while (true) {
1053
    TAOS_CHECK_EXIT(msmIsSnodeAlive(pMnode, snodeId, streamId, &alive));
323,144✔
1054

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

UNCOV
1072
      snodeId = pSnode->replicaId;
×
UNCOV
1073
      mndReleaseSnode(pMnode, pSnode);
×
1074
      
UNCOV
1075
      continue;
×
1076
    }
1077

1078
    mstsError("no available snode now, mainSnodeId:%d, followerSnodeId:%d", mainSnodeId, snodeId);
×
1079
    return 0;
×
1080
  }
1081

1082
_exit:
×
1083

1084
  if (code) {
×
1085
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1086
  }
1087

1088
  return 0;
×
1089
}
1090

1091
int32_t msmAssignRandomSnodeId(SMnode* pMnode, int64_t streamId) {
486,855✔
1092
  int32_t code = TSDB_CODE_SUCCESS;
486,855✔
1093
  int32_t lino = 0;
486,855✔
1094
  int32_t snodeIdx = 0;
486,855✔
1095
  int32_t snodeId = 0;
486,855✔
1096
  void      *pIter = NULL;
486,855✔
1097
  SSnodeObj *pObj = NULL;
486,855✔
1098
  bool alive = false;
486,855✔
1099
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
486,855✔
1100
  if (snodeNum <= 0) {
486,855✔
1101
    mstsInfo("no available snode now, num:%d", snodeNum);
2,390✔
1102
    goto _exit;
2,390✔
1103
  }
1104

1105
  int32_t snodeTarget = taosRand() % snodeNum;
484,465✔
1106

1107
  while (1) {
1108
    pIter = sdbFetch(pMnode->pSdb, SDB_SNODE, pIter, (void **)&pObj);
505,732✔
1109
    if (pIter == NULL) {
505,732✔
1110
      if (0 == snodeId) {
×
1111
        mstsError("no alive snode now, snodeNum:%d", snodeNum);
×
1112
        break;
×
1113
      }
1114
      
1115
      snodeId = 0;
×
1116
      continue;
×
1117
    }
1118

1119
    code = msmIsSnodeAlive(pMnode, pObj->id, streamId, &alive);
505,732✔
1120
    if (code) {
505,732✔
1121
      sdbRelease(pMnode->pSdb, pObj);
×
1122
      sdbCancelFetch(pMnode->pSdb, pIter);
×
1123
      pObj = NULL;
×
1124
      TAOS_CHECK_EXIT(code);
×
1125
    }
1126
    
1127
    if (!alive) {
505,732✔
1128
      sdbRelease(pMnode->pSdb, pObj);
×
1129
      continue;
×
1130
    }
1131

1132
    snodeId = pObj->id;
505,732✔
1133
    if (snodeIdx == snodeTarget) {
505,732✔
1134
      sdbRelease(pMnode->pSdb, pObj);
484,465✔
1135
      sdbCancelFetch(pMnode->pSdb, pIter);
484,465✔
1136
      pObj = NULL;
484,465✔
1137
      goto _exit;
484,465✔
1138
    }
1139

1140
    sdbRelease(pMnode->pSdb, pObj);
21,267✔
1141
    snodeIdx++;
21,267✔
1142
  }
1143

1144
_exit:
486,855✔
1145

1146
  if (code) {
486,855✔
1147
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1148
  }
1149

1150
  if (0 == snodeId) {
486,855✔
1151
    terrno = TSDB_CODE_SNODE_NO_AVAILABLE_NODE;
2,390✔
1152
  }
1153

1154
  return snodeId;
486,855✔
1155
}
1156

1157
int32_t msmAssignTaskSnodeId(SMnode* pMnode, SStreamObj* pStream, bool isStatic) {
643,168✔
1158
  int64_t streamId = pStream->pCreate->streamId;
643,168✔
1159
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
643,168✔
1160
  int32_t snodeId = 0;
643,168✔
1161
  if (snodeNum <= 0) {
643,168✔
1162
    mstsInfo("no available snode now, num:%d", snodeNum);
×
1163
    goto _exit;
×
1164
  }
1165

1166
  snodeId = isStatic ? msmRetrieveStaticSnodeId(pMnode, pStream) : msmAssignRandomSnodeId(pMnode, streamId);
643,168✔
1167

1168
_exit:
643,168✔
1169

1170
  if (0 == snodeId) {
643,168✔
1171
    terrno = TSDB_CODE_SNODE_NO_AVAILABLE_NODE;
×
1172
  }
1173

1174
  return snodeId;
643,168✔
1175
}
1176

1177

1178
static int32_t msmBuildTriggerTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
163,132✔
1179
  int32_t code = TSDB_CODE_SUCCESS;
163,132✔
1180
  int32_t lino = 0;
163,132✔
1181
  int64_t streamId = pStream->pCreate->streamId;
163,132✔
1182

1183
  pInfo->triggerTask = taosMemoryCalloc(1, sizeof(SStmTaskStatus));
163,132✔
1184
  TSDB_CHECK_NULL(pInfo->triggerTask, code, lino, _exit, terrno);
163,132✔
1185

1186
  pInfo->triggerTask->id.taskId = pCtx->triggerTaskId;
163,132✔
1187
  pInfo->triggerTask->id.deployId = 0;
163,132✔
1188
  pInfo->triggerTask->id.seriousId = msmAssignTaskSeriousId();
163,132✔
1189
  pInfo->triggerTask->id.nodeId = pCtx->triggerNodeId;
163,132✔
1190
  pInfo->triggerTask->id.taskIdx = 0;
163,132✔
1191
  pInfo->triggerTask->type = STREAM_TRIGGER_TASK;
163,132✔
1192
  pInfo->triggerTask->lastUpTs = pCtx->currTs;
163,132✔
1193
  pInfo->triggerTask->pStream = pInfo;
163,132✔
1194

1195
  SStmTaskDeploy info = {0};
163,132✔
1196
  info.task.type = pInfo->triggerTask->type;
163,132✔
1197
  info.task.streamId = streamId;
163,132✔
1198
  info.task.taskId =  pInfo->triggerTask->id.taskId;
163,132✔
1199
  info.task.seriousId = pInfo->triggerTask->id.seriousId;
163,132✔
1200
  info.task.nodeId =  pInfo->triggerTask->id.nodeId;
163,132✔
1201
  info.task.taskIdx =  pInfo->triggerTask->id.taskIdx;
163,132✔
1202
  TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pInfo, &info, pStream));
163,132✔
1203
  TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
163,132✔
1204
  
1205
  (void)atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
163,132✔
1206

1207
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pInfo->triggerTask));
163,132✔
1208
  TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, pInfo->triggerTask, 1, -1));
163,132✔
1209

1210
_exit:
163,132✔
1211

1212
  if (code) {
163,132✔
1213
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1214
  }
1215

1216
  return code;
163,132✔
1217
}
1218

1219
static int32_t msmTDAddSingleTrigReader(SStmGrpCtx* pCtx, SStmTaskStatus* pState, int32_t nodeId, SStmStatus* pInfo, int64_t streamId) {
252,680✔
1220
  int32_t code = TSDB_CODE_SUCCESS;
252,680✔
1221
  int32_t lino = 0;
252,680✔
1222

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

1245
_exit:
252,680✔
1246

1247
  if (code) {
252,680✔
1248
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1249
  }
1250

1251
  return code;
252,680✔
1252
}
1253

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

1283
      pInfo->trigReaders = taosArrayInit(pDb->cfg.numOfVgroups, sizeof(SStmTaskStatus));
67,633✔
1284
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
67,633✔
1285
      
1286
      void *pIter = NULL;
67,633✔
1287
      while (1) {
372,563✔
1288
        SStmTaskDeploy info = {0};
440,196✔
1289
        pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
440,196✔
1290
        if (pIter == NULL) {
440,196✔
1291
          break;
67,633✔
1292
        }
1293
      
1294
        if (pVgroup->dbUid == pDb->uid && !pVgroup->isTsma) {
372,563✔
1295
          pState = taosArrayReserve(pInfo->trigReaders, 1);
101,035✔
1296

1297
          code = msmTDAddSingleTrigReader(pCtx, pState, pVgroup->vgId, pInfo, streamId);
101,035✔
1298
          if (code) {
101,035✔
1299
            sdbRelease(pSdb, pVgroup);
×
1300
            sdbCancelFetch(pSdb, pIter);
×
1301
            pVgroup = NULL;
×
1302
            TAOS_CHECK_EXIT(code);
×
1303
          }
1304
        }
1305

1306
        sdbRelease(pSdb, pVgroup);
372,563✔
1307
      }
1308
      break;
67,633✔
1309
    }
1310
    default:
942✔
1311
      mstsDebug("%s ignore triggerTblType %d", __FUNCTION__, pStream->pCreate->triggerTblType);
942✔
1312
      break;
942✔
1313
  }
1314

1315
_exit:
163,132✔
1316

1317
  mndReleaseDb(pCtx->pMnode, pDb);
163,132✔
1318

1319
  if (code) {
163,132✔
1320
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1321
  }
1322

1323
  return code;
163,132✔
1324
}
1325

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

1349
  key[1] = pSubplan->id.subplanId;
241,050✔
1350

1351
  SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
241,050✔
1352
  if (NULL == ppRes) {
241,050✔
1353
    SArray* pRes = taosArrayInit(1, sizeof(addr));
241,050✔
1354
    TSDB_CHECK_NULL(pRes, code, lino, _exit, terrno);
241,050✔
1355
    TSDB_CHECK_NULL(taosArrayPush(pRes, &addr), code, lino, _exit, terrno);
482,100✔
1356
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.toUpdateScanMap, key, sizeof(key), &pRes, POINTER_BYTES));
241,050✔
1357
  } else {
1358
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &addr), code, lino, _exit, terrno);
×
1359
  }
1360

1361
  mstsDebug("calcReader %" PRIx64 " added to toUpdateScan, vgId:%d, groupId:%d, subplanId:%d", taskId, vgId, pSubplan->id.groupId, pSubplan->id.subplanId);
241,050✔
1362
  
1363
  (void)atomic_add_fetch_32(&mStreamMgmt.toUpdateScanNum, 1);
241,050✔
1364
  
1365
_exit:
241,050✔
1366

1367
  nodesDestroyNode((SNode*)pSubplan);
241,050✔
1368

1369
  if (code) {
241,050✔
1370
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1371
  }
1372

1373
  return code;
241,050✔
1374
}
1375

1376
int32_t msmUPAddCacheTask(SStmGrpCtx* pCtx, SStreamCalcScan* pScan, SStreamObj* pStream) {
75,024✔
1377
  int32_t code = TSDB_CODE_SUCCESS;
75,024✔
1378
  int32_t lino = 0;
75,024✔
1379
  SSubplan* pSubplan = NULL;
75,024✔
1380
  int64_t streamId = pStream->pCreate->streamId;
75,024✔
1381
  int64_t key[2] = {streamId, 0};
75,024✔
1382
  TAOS_CHECK_EXIT(nodesStringToNode(pScan->scanPlan, (SNode**)&pSubplan));
75,024✔
1383

1384
  SStmTaskSrcAddr addr;
75,024✔
1385
  addr.isFromCache = true;
75,024✔
1386
  addr.epset = mndGetDnodeEpsetById(pCtx->pMnode, pCtx->triggerNodeId);
75,024✔
1387
  addr.taskId = pCtx->triggerTaskId;
75,024✔
1388
  addr.vgId = pCtx->triggerNodeId;
75,024✔
1389
  addr.groupId = pSubplan->id.groupId;
75,024✔
1390

1391
  key[1] = pSubplan->id.subplanId;
75,024✔
1392
  SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
75,024✔
1393
  if (NULL == ppRes) {
75,024✔
1394
    SArray* pRes = taosArrayInit(1, sizeof(addr));
75,024✔
1395
    TSDB_CHECK_NULL(pRes, code, lino, _exit, terrno);
75,024✔
1396
    TSDB_CHECK_NULL(taosArrayPush(pRes, &addr), code, lino, _exit, terrno);
150,048✔
1397
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.toUpdateScanMap, key, sizeof(key), &pRes, POINTER_BYTES));
75,024✔
1398
  } else {
1399
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &addr), code, lino, _exit, terrno);
×
1400
  }
1401
  
1402
  (void)atomic_add_fetch_32(&mStreamMgmt.toUpdateScanNum, 1);
75,024✔
1403
  
1404
_exit:
75,024✔
1405

1406
  nodesDestroyNode((SNode*)pSubplan);
75,024✔
1407
  
1408
  if (code) {
75,024✔
1409
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1410
  }
1411

1412
  return code;
75,024✔
1413
}
1414

1415

1416
static int32_t msmTDAddSingleCalcReader(SStmGrpCtx* pCtx, SStmTaskStatus* pState, int32_t taskIdx, int32_t nodeId, void* calcScanPlan, SStmStatus* pInfo, int64_t streamId) {
243,349✔
1417
  int32_t code = TSDB_CODE_SUCCESS;
243,349✔
1418
  int32_t lino = 0;
243,349✔
1419

1420
  TAOS_CHECK_EXIT(mstGetScanUidFromPlan(streamId, calcScanPlan, &pState->id.uid));
243,349✔
1421

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

1444
_exit:
243,349✔
1445

1446
  if (code) {
243,349✔
1447
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1448
  }
1449

1450
  return code;
243,349✔
1451
}
1452

1453

1454
static int32_t msmTDAddCalcReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
163,132✔
1455
  int32_t code = TSDB_CODE_SUCCESS;
163,132✔
1456
  int32_t lino = 0;
163,132✔
1457
  int32_t calcTasksNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
163,132✔
1458
  int64_t streamId = pStream->pCreate->streamId;
163,132✔
1459
  SStmTaskStatus* pState = NULL;
163,132✔
1460
  pInfo->calcReaders = tdListNew(sizeof(SStmTaskStatus));
163,132✔
1461
  TSDB_CHECK_NULL(pInfo->calcReaders, code, lino, _exit, terrno);
163,132✔
1462

1463
  
1464
  for (int32_t i = 0; i < calcTasksNum; ++i) {
479,206✔
1465
    SStreamCalcScan* pScan = taosArrayGet(pInfo->pCreate->calcScanPlanList, i);
316,074✔
1466
    if (pScan->readFromCache) {
316,074✔
1467
      TAOS_CHECK_EXIT(msmUPAddCacheTask(pCtx, pScan, pStream));
75,024✔
1468
      continue;
75,024✔
1469
    }
1470
    
1471
    int32_t vgNum = taosArrayGetSize(pScan->vgList);
241,050✔
1472
    for (int32_t m = 0; m < vgNum; ++m) {
482,100✔
1473
      pState = tdListReserve(pInfo->calcReaders);
241,050✔
1474
      TSDB_CHECK_NULL(pState, code, lino, _exit, terrno);
241,050✔
1475

1476
      TAOS_CHECK_EXIT(msmTDAddSingleCalcReader(pCtx, pState, i, *(int32_t*)taosArrayGet(pScan->vgList, m), pScan->scanPlan, pInfo, streamId));
241,050✔
1477
      TAOS_CHECK_EXIT(msmUPAddScanTask(pCtx, pStream, pScan->scanPlan, pState->id.nodeId, pState->id.taskId));
241,050✔
1478
    }
1479
  }
1480

1481
_exit:
163,132✔
1482

1483
  if (code) {
163,132✔
1484
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1485
  }
1486

1487
  return code;
163,132✔
1488
}
1489

1490

1491

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

UNCOV
1519
_exit:
×
1520

UNCOV
1521
  if (code) {
×
1522
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1523
  }
1524

UNCOV
1525
  return code;
×
1526
}
1527

1528
static int32_t msmBuildReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
163,132✔
1529
  int32_t code = TSDB_CODE_SUCCESS;
163,132✔
1530
  int32_t lino = 0;
163,132✔
1531
  int64_t streamId = pStream->pCreate->streamId;
163,132✔
1532
  
1533
  TAOS_CHECK_EXIT(msmTDAddTrigReaderTasks(pCtx, pInfo, pStream));
163,132✔
1534
  TAOS_CHECK_EXIT(msmTDAddCalcReaderTasks(pCtx, pInfo, pStream));
163,132✔
1535

1536
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, pInfo->trigReaders, NULL, NULL));
163,132✔
1537
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, pInfo->calcReaders, NULL));
163,132✔
1538
  
1539
  TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, pInfo->trigReaders, NULL, NULL, true));
163,132✔
1540
  TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, pInfo->calcReaders, NULL, false));
163,132✔
1541
  
1542
_exit:
163,132✔
1543

1544
  if (code) {
163,132✔
1545
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1546
  }
1547
  
1548
  return code;
163,132✔
1549
}
1550

1551
int32_t msmUpdatePlanSourceAddr(SStreamTask* pTask, int64_t streamId, SSubplan* plan, int64_t clientId, SStmTaskSrcAddr* pSrc, int32_t msgType, int64_t srcSubplanId) {
966,960✔
1552
  SDownstreamSourceNode source = {
966,960✔
1553
      .type = QUERY_NODE_DOWNSTREAM_SOURCE,
1554
      .clientId = clientId,
1555
      .taskId = pSrc->taskId,
966,960✔
1556
      .sId = 0,
1557
      .execId = 0,
1558
      .fetchMsgType = msgType,
1559
      .localExec = false,
1560
  };
1561

1562
  source.addr.epSet = pSrc->epset;
966,960✔
1563
  source.addr.nodeId = pSrc->vgId;
966,960✔
1564

1565
  msttDebug("try to update subplan %d grp %d sourceAddr from subplan %" PRId64 ", clientId:%" PRIx64 ", srcTaskId:%" PRIx64 ", srcNodeId:%d, msgType:%s", 
966,960✔
1566
      plan->id.subplanId, pSrc->groupId, srcSubplanId, source.clientId, source.taskId, source.addr.nodeId, TMSG_INFO(source.fetchMsgType));
1567
  
1568
  return qSetSubplanExecutionNode(plan, pSrc->groupId, &source);
966,960✔
1569
}
1570

1571
int32_t msmGetTaskIdFromSubplanId(SStreamObj* pStream, SArray* pRunners, int32_t beginIdx, int32_t subplanId, int64_t* taskId, SStreamTask** ppParent) {
18,738✔
1572
  int64_t streamId = pStream->pCreate->streamId;
18,738✔
1573
  int32_t runnerNum = taosArrayGetSize(pRunners);
18,738✔
1574
  for (int32_t i = beginIdx; i < runnerNum; ++i) {
47,754✔
1575
    SStmTaskDeploy* pDeploy = taosArrayGet(pRunners, i);
47,754✔
1576
    SSubplan* pPlan = pDeploy->msg.runner.pPlan;
47,754✔
1577
    if (pPlan->id.subplanId == subplanId) {
47,754✔
1578
      *taskId = pDeploy->task.taskId;
18,738✔
1579
      *ppParent = &pDeploy->task;
18,738✔
1580
      return TSDB_CODE_SUCCESS;
18,738✔
1581
    }
1582
  }
1583

1584
  mstsError("subplanId %d not found in runner list", subplanId);
×
1585

1586
  return TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
1587
}
1588

1589
int32_t msmUpdateLowestPlanSourceAddr(SSubplan* pPlan, SStmTaskDeploy* pDeploy, int64_t streamId) {
498,774✔
1590
  int32_t code = TSDB_CODE_SUCCESS;
498,774✔
1591
  int32_t lino = 0;
498,774✔
1592
  int64_t key[2] = {streamId, -1};
498,774✔
1593
  SNode* pNode = NULL;
498,774✔
1594
  SStreamTask* pTask = &pDeploy->task;
498,774✔
1595
  FOREACH(pNode, pPlan->pChildren) {
1,465,734✔
1596
    if (QUERY_NODE_VALUE != nodeType(pNode)) {
966,960✔
1597
      msttDebug("node type %d is not valueNode, skip it", nodeType(pNode));
18,738✔
1598
      continue;
18,738✔
1599
    }
1600
    
1601
    SValueNode* pVal = (SValueNode*)pNode;
948,222✔
1602
    if (TSDB_DATA_TYPE_BIGINT != pVal->node.resType.type) {
948,222✔
1603
      msttWarn("invalid value node data type %d for runner's child subplan", pVal->node.resType.type);
×
1604
      continue;
×
1605
    }
1606

1607
    key[1] = MND_GET_RUNNER_SUBPLANID(pVal->datum.i);
948,222✔
1608

1609
    SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
948,222✔
1610
    if (NULL == ppRes) {
948,222✔
1611
      msttError("lowest runner subplan ID:%d,%d can't get its child ID:%" PRId64 " addr", pPlan->id.groupId, pPlan->id.subplanId, key[1]);
×
1612
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1613
    }
1614

1615
    int32_t childrenNum = taosArrayGetSize(*ppRes);
948,222✔
1616
    for (int32_t i = 0; i < childrenNum; ++i) {
1,896,444✔
1617
      SStmTaskSrcAddr* pAddr = taosArrayGet(*ppRes, i);
948,222✔
1618
      TAOS_CHECK_EXIT(msmUpdatePlanSourceAddr(pTask, streamId, pPlan, pDeploy->task.taskId, pAddr, pAddr->isFromCache ? TDMT_STREAM_FETCH_FROM_CACHE : TDMT_STREAM_FETCH, key[1]));
948,222✔
1619
    }
1620
  }
1621

1622
_exit:
498,774✔
1623

1624
  if (code) {
498,774✔
1625
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1626
  }
1627

1628
  return code;
498,774✔
1629
}
1630

1631
int32_t msmUpdateRunnerPlan(SStmGrpCtx* pCtx, SArray* pRunners, int32_t beginIdx, SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
498,774✔
1632
  int32_t code = TSDB_CODE_SUCCESS;
498,774✔
1633
  int32_t lino = 0;
498,774✔
1634
  SSubplan* pPlan = pDeploy->msg.runner.pPlan;
498,774✔
1635
  SStreamTask* pTask = &pDeploy->task;
498,774✔
1636
  SStreamTask* parentTask = NULL;
498,774✔
1637
  int64_t streamId = pStream->pCreate->streamId;
498,774✔
1638

1639
  TAOS_CHECK_EXIT(msmUpdateLowestPlanSourceAddr(pPlan, pDeploy, streamId));
498,774✔
1640

1641
  SNode* pTmp = NULL;
498,774✔
1642
  WHERE_EACH(pTmp, pPlan->pChildren) {
1,465,734✔
1643
    if (QUERY_NODE_VALUE == nodeType(pTmp)) {
966,960✔
1644
      ERASE_NODE(pPlan->pChildren);
948,222✔
1645
      continue;
948,222✔
1646
    }
1647
    WHERE_NEXT;
18,738✔
1648
  }
1649
  nodesClearList(pPlan->pChildren);
498,774✔
1650
  pPlan->pChildren = NULL;
498,774✔
1651

1652
  if (NULL == pPlan->pParents) {
498,774✔
1653
    goto _exit;
480,036✔
1654
  }
1655

1656
  SNode* pNode = NULL;
18,738✔
1657
  int64_t parentTaskId = 0;
18,738✔
1658
  SStmTaskSrcAddr addr = {0};
18,738✔
1659
  addr.taskId = pDeploy->task.taskId;
18,738✔
1660
  addr.vgId = pDeploy->task.nodeId;
18,738✔
1661
  addr.groupId = pPlan->id.groupId;
18,738✔
1662
  addr.epset = mndGetDnodeEpsetById(pCtx->pMnode, pDeploy->task.nodeId);
18,738✔
1663
  FOREACH(pNode, pPlan->pParents) {
37,476✔
1664
    SSubplan* pSubplan = (SSubplan*)pNode;
18,738✔
1665
    TAOS_CHECK_EXIT(msmGetTaskIdFromSubplanId(pStream, pRunners, beginIdx, pSubplan->id.subplanId, &parentTaskId, &parentTask));
18,738✔
1666
    TAOS_CHECK_EXIT(msmUpdatePlanSourceAddr(parentTask, streamId, pSubplan, parentTaskId, &addr, TDMT_STREAM_FETCH_FROM_RUNNER, pPlan->id.subplanId));
18,738✔
1667
  }
1668
  
1669
_exit:
497,640✔
1670

1671
  if (code) {
498,774✔
1672
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1673
  }
1674

1675
  return code;
498,774✔
1676
}
1677

1678
int32_t msmUpdateRunnerPlans(SStmGrpCtx* pCtx, SArray* pRunners, SStreamObj* pStream) {
480,036✔
1679
  int32_t code = TSDB_CODE_SUCCESS;
480,036✔
1680
  int32_t lino = 0;
480,036✔
1681
  int64_t streamId = pStream->pCreate->streamId;
480,036✔
1682
  int32_t runnerNum = taosArrayGetSize(pRunners);
480,036✔
1683
  
1684
  for (int32_t i = 0; i < runnerNum; ++i) {
978,810✔
1685
    SStmTaskDeploy* pDeploy = taosArrayGet(pRunners, i);
498,774✔
1686
    TAOS_CHECK_EXIT(msmUpdateRunnerPlan(pCtx, pRunners, i, pDeploy, pStream));
498,774✔
1687
    TAOS_CHECK_EXIT(nodesNodeToString((SNode*)pDeploy->msg.runner.pPlan, false, (char**)&pDeploy->msg.runner.pPlan, NULL));
498,774✔
1688

1689
    SStreamTask* pTask = &pDeploy->task;
498,774✔
1690
    msttDebugL("runner updated task plan:%s", (const char*)pDeploy->msg.runner.pPlan);
498,774✔
1691
  }
1692

1693
_exit:
480,036✔
1694

1695
  if (code) {
480,036✔
1696
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1697
  }
1698

1699
  return code;
480,036✔
1700
}
1701

1702
int32_t msmBuildRunnerTasksImpl(SStmGrpCtx* pCtx, SQueryPlan* pDag, SStmStatus* pInfo, SStreamObj* pStream) {
160,012✔
1703
  int32_t code = 0;
160,012✔
1704
  int32_t lino = 0;
160,012✔
1705
  int64_t streamId = pStream->pCreate->streamId;
160,012✔
1706
  SArray* deployTaskList = NULL;
160,012✔
1707
  SArray* deployList = NULL;
160,012✔
1708
  int32_t deployNodeId = 0;
160,012✔
1709
  SStmTaskStatus* pState = NULL;
160,012✔
1710
  int32_t taskIdx = 0;
160,012✔
1711
  SNodeListNode *plans = NULL;
160,012✔
1712
  int32_t        taskNum = 0;
160,012✔
1713
  int32_t        totalTaskNum = 0;
160,012✔
1714

1715
  if (pDag->numOfSubplans <= 0) {
160,012✔
1716
    mstsError("invalid subplan num:%d", pDag->numOfSubplans);
×
1717
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1718
  }
1719

1720
  if (pDag->numOfSubplans != pStream->pCreate->numOfCalcSubplan) {
160,012✔
1721
    mstsError("numOfCalcSubplan %d mismatch with numOfSubplans %d", pStream->pCreate->numOfCalcSubplan, pDag->numOfSubplans);
×
1722
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1723
  }
1724

1725
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
160,012✔
1726
  if (levelNum <= 0) {
160,012✔
1727
    mstsError("invalid level num:%d", levelNum);
×
1728
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1729
  }
1730

1731
  int32_t        lowestLevelIdx = levelNum - 1;
160,012✔
1732
  
1733
  plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, 0);
160,012✔
1734
  if (QUERY_NODE_NODE_LIST != nodeType(plans)) {
160,012✔
1735
    mstsError("invalid level plan, level:0, planNodeType:%d", nodeType(plans));
×
1736
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1737
  }
1738
  
1739
  taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
160,012✔
1740
  if (taskNum != 1) {
160,012✔
1741
    mstsError("invalid level plan number:%d, level:0", taskNum);
×
1742
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1743
  }
1744

1745
  deployTaskList = taosArrayInit_s(sizeof(SStmTaskDeploy), pDag->numOfSubplans);
160,012✔
1746
  TSDB_CHECK_NULL(deployTaskList, code, lino, _exit, terrno);
160,012✔
1747
  
1748
  for (int32_t deployId = 0; deployId < pInfo->runnerDeploys; ++deployId) {
640,048✔
1749
    totalTaskNum = 0;
480,036✔
1750

1751
    deployList = pInfo->runners[deployId];
480,036✔
1752
    deployNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, (0 == deployId) ? true : false);
480,036✔
1753
    if (!GOT_SNODE(deployNodeId)) {
480,036✔
1754
      TAOS_CHECK_EXIT(terrno);
×
1755
    }
1756

1757
    taskIdx = 0;
480,036✔
1758
    
1759
    for (int32_t i = lowestLevelIdx; i >= 0; --i) {
969,138✔
1760
      plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
489,102✔
1761
      if (NULL == plans) {
489,102✔
1762
        mstsError("empty level plan, level:%d", i);
×
1763
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1764
      }
1765

1766
      if (QUERY_NODE_NODE_LIST != nodeType(plans)) {
489,102✔
1767
        mstsError("invalid level plan, level:%d, planNodeType:%d", i, nodeType(plans));
×
1768
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1769
      }
1770

1771
      taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
489,102✔
1772
      if (taskNum <= 0) {
489,102✔
1773
        mstsError("invalid level plan number:%d, level:%d", taskNum, i);
×
1774
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1775
      }
1776

1777
      totalTaskNum += taskNum;
489,102✔
1778
      if (totalTaskNum > pDag->numOfSubplans) {
489,102✔
1779
        mstsError("current totalTaskNum %d is bigger than numOfSubplans %d, level:%d", totalTaskNum, pDag->numOfSubplans, i);
×
1780
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1781
      }
1782

1783
      for (int32_t n = 0; n < taskNum; ++n) {
987,876✔
1784
        SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
498,774✔
1785
        pState = taosArrayReserve(deployList, 1);
498,774✔
1786

1787
        pState->id.taskId = msmAssignTaskId();
498,774✔
1788
        pState->id.deployId = deployId;
498,774✔
1789
        pState->id.seriousId = msmAssignTaskSeriousId();
498,774✔
1790
        pState->id.nodeId = deployNodeId;
498,774✔
1791
        pState->id.taskIdx = MND_SET_RUNNER_TASKIDX(i, n);
498,774✔
1792
        pState->type = STREAM_RUNNER_TASK;
498,774✔
1793
        pState->flags = (0 == i) ? STREAM_FLAG_TOP_RUNNER : 0;
498,774✔
1794
        pState->status = STREAM_STATUS_UNDEPLOYED;
498,774✔
1795
        pState->lastUpTs = pCtx->currTs;
498,774✔
1796
        pState->pStream = pInfo;
498,774✔
1797

1798
        SStmTaskDeploy* pDeploy = taosArrayGet(deployTaskList, taskIdx++);
498,774✔
1799
        pDeploy->task.type = pState->type;
498,774✔
1800
        pDeploy->task.streamId = streamId;
498,774✔
1801
        pDeploy->task.taskId = pState->id.taskId;
498,774✔
1802
        pDeploy->task.flags = pState->flags;
498,774✔
1803
        pDeploy->task.seriousId = pState->id.seriousId;
498,774✔
1804
        pDeploy->task.deployId = pState->id.deployId;
498,774✔
1805
        pDeploy->task.nodeId = pState->id.nodeId;
498,774✔
1806
        pDeploy->task.taskIdx = pState->id.taskIdx;
498,774✔
1807
        TAOS_CHECK_EXIT(msmBuildRunnerDeployInfo(pDeploy, plan, pStream, pInfo, 0 == i));
498,774✔
1808

1809
        SStreamTask* pTask = &pDeploy->task;
498,774✔
1810
        msttDebug("runner task deploy built, subplan level:%d, taskIdx:%d, groupId:%d, subplanId:%d",
498,774✔
1811
            i, pTask->taskIdx, plan->id.groupId, plan->id.subplanId);
1812
      }
1813

1814
      mstsDebug("deploy %d level %d initialized, taskNum:%d", deployId, i, taskNum);
489,102✔
1815
    }
1816

1817
    if (totalTaskNum != pDag->numOfSubplans) {
480,036✔
1818
      mstsError("totalTaskNum %d mis-match with numOfSubplans %d", totalTaskNum, pDag->numOfSubplans);
×
1819
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1820
    }
1821

1822
    TAOS_CHECK_EXIT(msmUpdateRunnerPlans(pCtx, deployTaskList, pStream));
480,036✔
1823

1824
    TAOS_CHECK_EXIT(msmTDAddRunnersToSnodeMap(deployTaskList, pStream));
480,036✔
1825

1826
    nodesDestroyNode((SNode *)pDag);
480,036✔
1827
    pDag = NULL;
480,036✔
1828
    
1829
    TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pDag));
480,036✔
1830

1831
    mstsDebug("total %d runner tasks added for deploy %d", totalTaskNum, deployId);
480,036✔
1832
  }
1833

1834
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
640,048✔
1835
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, pInfo->runners[i], NULL, NULL));
480,036✔
1836
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, pInfo->runners[i], NULL, 0, i));
480,036✔
1837
  }
1838
  
1839
  pInfo->runnerNum = totalTaskNum;
160,012✔
1840
  
1841
_exit:
160,012✔
1842

1843
  if (code) {
160,012✔
1844
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1845
  }
1846

1847
  taosArrayDestroy(deployTaskList);
160,012✔
1848
  nodesDestroyNode((SNode *)pDag);
160,012✔
1849

1850
  return code;
160,012✔
1851
}
1852

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

UNCOV
1870
  for (int32_t r = 0; r < pAction->deployNum; ++r) {
×
UNCOV
1871
    deployId = pAction->deployId[r];
×
1872

UNCOV
1873
    pRunner = taosArrayGet(pInfo->runners[deployId], 0);
×
1874

UNCOV
1875
    pStartRunner = pRunner;
×
UNCOV
1876
    totalTaskNum = 0;
×
1877

UNCOV
1878
    newNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, (0 == r) ? true : false);
×
UNCOV
1879
    if (!GOT_SNODE(newNodeId)) {
×
1880
      TAOS_CHECK_EXIT(terrno);
×
1881
    }
1882

UNCOV
1883
    taskIdx = 0;
×
1884
    
UNCOV
1885
    for (int32_t i = lowestLevelIdx; i >= 0; --i) {
×
UNCOV
1886
      plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
×
UNCOV
1887
      taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
×
UNCOV
1888
      totalTaskNum += taskNum;
×
1889

UNCOV
1890
      pRunner->flags &= STREAM_FLAG_REDEPLOY_RUNNER;
×
1891
      
UNCOV
1892
      for (int32_t n = 0; n < taskNum; ++n) {
×
UNCOV
1893
        SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
×
1894

UNCOV
1895
        int32_t newTaskIdx = MND_SET_RUNNER_TASKIDX(i, n);
×
UNCOV
1896
        if (pRunner->id.taskIdx != newTaskIdx) {
×
1897
          mstsError("runner TASK:%" PRId64 " taskIdx %d mismatch with newTaskIdx:%d", pRunner->id.taskId, pRunner->id.taskIdx, newTaskIdx);
×
1898
          TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
1899
        }
1900

UNCOV
1901
        pRunner->id.nodeId = newNodeId;
×
1902

UNCOV
1903
        SStmTaskDeploy* pDeploy = taosArrayGet(deployTaskList, taskIdx++);
×
UNCOV
1904
        pDeploy->task.type = pRunner->type;
×
UNCOV
1905
        pDeploy->task.streamId = streamId;
×
UNCOV
1906
        pDeploy->task.taskId = pRunner->id.taskId;
×
UNCOV
1907
        pDeploy->task.flags = pRunner->flags;
×
UNCOV
1908
        pDeploy->task.seriousId = pRunner->id.seriousId;
×
UNCOV
1909
        pDeploy->task.nodeId = pRunner->id.nodeId;
×
UNCOV
1910
        pDeploy->task.taskIdx = pRunner->id.taskIdx;
×
UNCOV
1911
        TAOS_CHECK_EXIT(msmBuildRunnerDeployInfo(pDeploy, plan, pStream, pInfo, 0 == i));
×
1912

UNCOV
1913
        pRunner++;
×
1914
      }
1915

UNCOV
1916
      mstsDebug("level %d initialized, taskNum:%d", i, taskNum);
×
1917
    }
1918

UNCOV
1919
    TAOS_CHECK_EXIT(msmUpdateRunnerPlans(pCtx, deployTaskList, pStream));
×
1920

UNCOV
1921
    TAOS_CHECK_EXIT(msmTDAddRunnersToSnodeMap(deployTaskList, pStream));
×
1922

UNCOV
1923
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, pInfo->runners[deployId], NULL, 0, deployId));
×
1924

UNCOV
1925
    nodesDestroyNode((SNode *)pDag);
×
UNCOV
1926
    pDag = NULL;
×
1927

UNCOV
1928
    TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pDag));
×
1929
  }
1930

UNCOV
1931
_exit:
×
1932

UNCOV
1933
  if (code) {
×
1934
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1935
  }
1936

UNCOV
1937
  nodesDestroyNode((SNode *)pDag);
×
UNCOV
1938
  taosArrayDestroy(deployTaskList);
×
1939

UNCOV
1940
  return code;
×
1941
}
1942

1943

1944
int32_t msmSetStreamRunnerExecReplica(int64_t streamId, SStmStatus* pInfo) {
154,048✔
1945
  int32_t code = TSDB_CODE_SUCCESS;
154,048✔
1946
  int32_t lino = 0;
154,048✔
1947
  //STREAMTODO 
1948
  
1949
  pInfo->runnerDeploys = MND_STREAM_RUNNER_DEPLOY_NUM;
154,048✔
1950
  pInfo->runnerReplica = MND_STREAM_RUNNER_REPLICA_NUM;
154,048✔
1951

1952
_exit:
154,048✔
1953

1954
  if (code) {
154,048✔
1955
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1956
  }
1957

1958
  return code;
154,048✔
1959
}
1960

1961

1962
static int32_t msmBuildRunnerTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
163,132✔
1963
  if (NULL == pStream->pCreate->calcPlan) {
163,132✔
1964
    return TSDB_CODE_SUCCESS;
3,120✔
1965
  }
1966
  
1967
  int32_t code = TSDB_CODE_SUCCESS;
160,012✔
1968
  int32_t lino = 0;
160,012✔
1969
  int64_t streamId = pStream->pCreate->streamId;
160,012✔
1970
  SQueryPlan* pPlan = NULL;
160,012✔
1971

1972
  TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pPlan));
160,012✔
1973

1974
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
640,048✔
1975
    pInfo->runners[i] = taosArrayInit(pPlan->numOfSubplans, sizeof(SStmTaskStatus));
480,036✔
1976
    TSDB_CHECK_NULL(pInfo->runners[i], code, lino, _exit, terrno);
480,036✔
1977
  }
1978

1979
  code = msmBuildRunnerTasksImpl(pCtx, pPlan, pInfo, pStream);
160,012✔
1980
  pPlan = NULL;
160,012✔
1981
  
1982
  TAOS_CHECK_EXIT(code);
160,012✔
1983

1984
  taosHashClear(mStreamMgmt.toUpdateScanMap);
160,012✔
1985
  mStreamMgmt.toUpdateScanNum = 0;
160,012✔
1986

1987
_exit:
160,012✔
1988

1989
  nodesDestroyNode((SNode *)pPlan);
160,012✔
1990

1991
  if (code) {
160,012✔
1992
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1993
  }
1994

1995
  return code;
160,012✔
1996
}
1997

1998

1999
static int32_t msmBuildStreamTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
163,132✔
2000
  int32_t code = TSDB_CODE_SUCCESS;
163,132✔
2001
  int32_t lino = 0;
163,132✔
2002
  int64_t streamId = pStream->pCreate->streamId;
163,132✔
2003

2004
  mstsInfo("start to deploy stream tasks, deployTimes:%" PRId64, pInfo->deployTimes);
163,132✔
2005

2006
  pCtx->triggerTaskId = msmAssignTaskId();
163,132✔
2007
  pCtx->triggerNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
163,132✔
2008
  if (!GOT_SNODE(pCtx->triggerNodeId)) {
163,132✔
2009
    TAOS_CHECK_EXIT(terrno);
×
2010
  }
2011

2012
  TAOS_CHECK_EXIT(msmBuildReaderTasks(pCtx, pInfo, pStream));
163,132✔
2013
  TAOS_CHECK_EXIT(msmBuildRunnerTasks(pCtx, pInfo, pStream));
163,132✔
2014
  TAOS_CHECK_EXIT(msmBuildTriggerTasks(pCtx, pInfo, pStream));
163,132✔
2015
  
2016
_exit:
163,132✔
2017

2018
  if (code) {
163,132✔
2019
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2020
  }
2021

2022
  return code;
163,132✔
2023
}
2024

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

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

2064
_exit:
×
2065

2066
  if (code) {
×
2067
    mndReleaseDb(pCtx->pMnode, pDb);
×
2068
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2069
  }
2070

2071
  return code;
×
2072
}
2073

2074

2075
static int32_t msmInitStmStatus(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStreamObj* pStream, bool initList) {
157,168✔
2076
  int32_t code = TSDB_CODE_SUCCESS;
157,168✔
2077
  int32_t lino = 0;
157,168✔
2078
  int64_t streamId = pStream->pCreate->streamId;
157,168✔
2079

2080
  pStatus->lastActionTs = INT64_MIN;
157,168✔
2081

2082
  if (NULL == pStatus->streamName) {
157,168✔
2083
    pStatus->streamName = taosStrdup(pStream->name);
157,168✔
2084
    TSDB_CHECK_NULL(pStatus->streamName, code, lino, _exit, terrno);
157,168✔
2085
  }
2086

2087
  TAOS_CHECK_EXIT(tCloneStreamCreateDeployPointers(pStream->pCreate, &pStatus->pCreate));
157,168✔
2088
  
2089
  if (pStream->pCreate->numOfCalcSubplan > 0) {
157,168✔
2090
    pStatus->runnerNum = pStream->pCreate->numOfCalcSubplan;
154,048✔
2091
    
2092
    TAOS_CHECK_EXIT(msmSetStreamRunnerExecReplica(streamId, pStatus));
154,048✔
2093
  }
2094

2095
  if (initList) {
157,168✔
2096
    TAOS_CHECK_EXIT(msmInitTrigReaderList(pCtx, pStatus, pStream));
×
2097

2098
    int32_t subPlanNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
×
2099
    if (subPlanNum > 0) {
×
2100
      pStatus->calcReaderNum = subPlanNum;
×
2101
      pStatus->calcReaders = tdListNew(sizeof(SStmTaskStatus));
×
2102
      TSDB_CHECK_NULL(pStatus->calcReaders, code, lino, _exit, terrno);
×
2103
    }
2104

2105
    if (pStatus->runnerNum > 0) {
×
2106
      for (int32_t i = 0; i < pStatus->runnerDeploys; ++i) {
×
2107
        pStatus->runners[i] = taosArrayInit(pStatus->runnerNum, sizeof(SStmTaskStatus));
×
2108
        TSDB_CHECK_NULL(pStatus->runners[i], code, lino, _exit, terrno);
×
2109
      }
2110
    }
2111
  }
2112
  
2113
_exit:
157,168✔
2114

2115
  if (code) {
157,168✔
2116
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2117
  }
2118

2119
  return code;
157,168✔
2120
}
2121

2122
static int32_t msmDeployStreamTasks(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmStatus* pStatus) {
163,132✔
2123
  int32_t code = TSDB_CODE_SUCCESS;
163,132✔
2124
  int32_t lino = 0;
163,132✔
2125
  int64_t streamId = pStream->pCreate->streamId;
163,132✔
2126
  SStmStatus info = {0};
163,132✔
2127

2128
  if (NULL == pStatus) {
163,132✔
2129
    TAOS_CHECK_EXIT(msmInitStmStatus(pCtx, &info, pStream, false));
157,168✔
2130

2131
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.streamMap, &streamId, sizeof(streamId), &info, sizeof(info)));
157,168✔
2132

2133
    pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
157,168✔
2134
  }
2135
  
2136
  TAOS_CHECK_EXIT(msmBuildStreamTasks(pCtx, pStatus, pStream));
163,132✔
2137

2138
  mstLogSStmStatus("stream deployed", streamId, pStatus);
163,132✔
2139

2140
_exit:
163,132✔
2141

2142
  if (code) {
163,132✔
2143
    if (NULL != pStatus) {
×
2144
      msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
2145
      mstsError("stream build error:%s, will try to stop current stream", tstrerror(code));
×
2146
    }
2147
    
2148
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2149
  }
2150

2151
  return code;
163,132✔
2152
}
2153

2154

2155
static int32_t msmSTRemoveStream(int64_t streamId, bool fromStreamMap) {
6,370✔
2156
  int32_t code = TSDB_CODE_SUCCESS;
6,370✔
2157
  void* pIter = NULL;
6,370✔
2158

2159
  while ((pIter = taosHashIterate(mStreamMgmt.toDeployVgMap, pIter))) {
10,027✔
2160
    SStmVgTasksToDeploy* pVg = (SStmVgTasksToDeploy*)pIter;
3,657✔
2161
    (void)mstWaitLock(&pVg->lock, true);
3,657✔
2162

2163
    int32_t taskNum = taosArrayGetSize(pVg->taskList);
3,657✔
2164
    if (atomic_load_32(&pVg->deployed) == taskNum) {
3,657✔
2165
      taosRUnLockLatch(&pVg->lock);
×
2166
      continue;
×
2167
    }
2168

2169
    for (int32_t i = 0; i < taskNum; ++i) {
19,313✔
2170
      SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, i);
15,656✔
2171
      if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
15,656✔
2172
        continue;
14,188✔
2173
      }
2174

2175
      mstDestroySStmTaskToDeployExt(pExt);
1,468✔
2176
      pExt->deployed = true;
1,468✔
2177
    }
2178
    
2179
    taosRUnLockLatch(&pVg->lock);
3,657✔
2180
  }
2181

2182
  while ((pIter = taosHashIterate(mStreamMgmt.toDeploySnodeMap, pIter))) {
12,421✔
2183
    SStmSnodeTasksDeploy* pSnode = (SStmSnodeTasksDeploy*)pIter;
6,051✔
2184
    (void)mstWaitLock(&pSnode->lock, true);
6,051✔
2185

2186
    int32_t taskNum = taosArrayGetSize(pSnode->triggerList);
6,051✔
2187
    if (atomic_load_32(&pSnode->triggerDeployed) != taskNum) {
6,051✔
2188
      for (int32_t i = 0; i < taskNum; ++i) {
12,201✔
2189
        SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, i);
8,031✔
2190
        if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
8,031✔
2191
          continue;
7,297✔
2192
        }
2193
        
2194
        mstDestroySStmTaskToDeployExt(pExt);
734✔
2195
        pExt->deployed = true;
734✔
2196
      }
2197
    }
2198

2199
    taskNum = taosArrayGetSize(pSnode->runnerList);
6,051✔
2200
    if (atomic_load_32(&pSnode->runnerDeployed) != taskNum) {
6,051✔
2201
      for (int32_t i = 0; i < taskNum; ++i) {
30,144✔
2202
        SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, i);
24,093✔
2203
        if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
24,093✔
2204
          continue;
21,891✔
2205
        }
2206
        
2207
        mstDestroySStmTaskToDeployExt(pExt);
2,202✔
2208
        pExt->deployed = true;
2,202✔
2209
      }
2210
    }
2211

2212
    taosRUnLockLatch(&pSnode->lock);
6,051✔
2213
  }
2214

2215
  
2216
  while ((pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter))) {
19,409✔
2217
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
13,039✔
2218
    code = taosHashRemove(pSnode->streamTasks, &streamId, sizeof(streamId));
13,039✔
2219
    if (TSDB_CODE_SUCCESS == code) {
13,039✔
2220
      mstsDebug("stream removed from snodeMap %d, remainStreams:%d", *(int32_t*)taosHashGetKey(pIter, NULL), (int32_t)taosHashGetSize(pSnode->streamTasks));
8,422✔
2221
    }
2222
  }
2223

2224
  while ((pIter = taosHashIterate(mStreamMgmt.vgroupMap, pIter))) {
26,981✔
2225
    SStmVgroupStatus* pVg = (SStmVgroupStatus*)pIter;
20,611✔
2226
    code = taosHashRemove(pVg->streamTasks, &streamId, sizeof(streamId));
20,611✔
2227
    if (TSDB_CODE_SUCCESS == code) {
20,611✔
2228
      mstsDebug("stream removed from vgroupMap %d, remainStreams:%d", *(int32_t*)taosHashGetKey(pIter, NULL), (int32_t)taosHashGetSize(pVg->streamTasks));
9,100✔
2229
    }
2230
  }
2231

2232
  size_t keyLen = 0;
6,370✔
2233
  while ((pIter = taosHashIterate(mStreamMgmt.taskMap, pIter))) {
408,008✔
2234
    int64_t* pStreamId = taosHashGetKey(pIter, &keyLen);
401,638✔
2235
    if (*pStreamId == streamId) {
401,638✔
2236
      int64_t taskId = *(pStreamId + 1);
39,568✔
2237
      code = taosHashRemove(mStreamMgmt.taskMap, pStreamId, keyLen);
39,568✔
2238
      if (code) {
39,568✔
2239
        mstsError("TASK:%" PRIx64 " remove from taskMap failed, error:%s", taskId, tstrerror(code));
×
2240
      } else {
2241
        mstsDebug("TASK:%" PRIx64 " removed from taskMap", taskId);
39,568✔
2242
      }
2243
    }
2244
  }
2245

2246
  if (fromStreamMap) {
6,370✔
2247
    code = taosHashRemove(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
406✔
2248
    if (code) {
406✔
2249
      mstsError("stream remove from streamMap failed, error:%s", tstrerror(code));
×
2250
    } else {
2251
      mstsDebug("stream removed from streamMap, remains:%d", taosHashGetSize(mStreamMgmt.streamMap));
406✔
2252
    }
2253
  }
2254
  
2255
  return code;
6,370✔
2256
}
2257

2258
static void msmResetStreamForRedeploy(int64_t streamId, SStmStatus* pStatus) {
5,964✔
2259
  mstsInfo("try to reset stream for redeploy, stopped:%d, current deployTimes:%" PRId64, atomic_load_8(&pStatus->stopped), pStatus->deployTimes);
5,964✔
2260
  
2261
  (void)msmSTRemoveStream(streamId, false);  
5,964✔
2262

2263
  mstResetSStmStatus(pStatus);
5,964✔
2264

2265
  pStatus->deployTimes++;
5,964✔
2266
}
5,964✔
2267

2268
static int32_t msmLaunchStreamDeployAction(SStmGrpCtx* pCtx, SStmStreamAction* pAction) {
164,155✔
2269
  int32_t code = TSDB_CODE_SUCCESS;
164,155✔
2270
  int32_t lino = 0;
164,155✔
2271
  int64_t streamId = pAction->streamId;
164,155✔
2272
  char* streamName = pAction->streamName;
164,155✔
2273
  SStreamObj* pStream = NULL;
164,155✔
2274
  int8_t stopped = 0;
164,155✔
2275

2276
  SStmStatus* pStatus = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
164,155✔
2277
  if (pStatus) {
164,155✔
2278
    stopped = atomic_load_8(&pStatus->stopped);
5,964✔
2279
    if (0 == stopped) {
5,964✔
2280
      mstsDebug("stream %s will try to reset and redeploy it", pAction->streamName);
734✔
2281
      msmResetStreamForRedeploy(streamId, pStatus);
734✔
2282
    } else {
2283
      if (MST_IS_USER_STOPPED(stopped) && !pAction->userAction) {
5,230✔
2284
        mstsWarn("stream %s already stopped by user, stopped:%d, ignore deploy it", pAction->streamName, stopped);
×
2285
        return code;
×
2286
      }
2287
      
2288
      if (stopped == atomic_val_compare_exchange_8(&pStatus->stopped, stopped, 0)) {
5,230✔
2289
        mstsDebug("stream %s will try to reset and redeploy it from stopped %d", pAction->streamName, stopped);
5,230✔
2290
        msmResetStreamForRedeploy(streamId, pStatus);
5,230✔
2291
      }
2292
    }
2293
  }
2294

2295
  code = mndAcquireStream(pCtx->pMnode, streamName, &pStream);
164,155✔
2296
  if (TSDB_CODE_MND_STREAM_NOT_EXIST == code) {
164,155✔
2297
    mstsWarn("stream %s no longer exists, ignore deploy", streamName);
605✔
2298
    return TSDB_CODE_SUCCESS;
605✔
2299
  }
2300

2301
  TAOS_CHECK_EXIT(code);
163,550✔
2302

2303
  if (pStatus && pStream->pCreate->streamId != streamId) {
163,550✔
2304
    mstsWarn("stream %s already dropped by user, ignore deploy it", pAction->streamName);
×
2305
    atomic_store_8(&pStatus->stopped, 2);
×
2306
    mstsInfo("set stream %s stopped by user since streamId mismatch", streamName);
×
2307
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_EXIST);
×
2308
  }
2309

2310
  int8_t userStopped = atomic_load_8(&pStream->userStopped);
163,550✔
2311
  int8_t userDropped = atomic_load_8(&pStream->userDropped);
163,550✔
2312
  if (userStopped || userDropped) {
163,550✔
2313
    mstsWarn("stream %s is stopped %d or removing %d, ignore deploy", streamName, userStopped, userDropped);
418✔
2314
    goto _exit;
418✔
2315
  }
2316
  
2317
  TAOS_CHECK_EXIT(msmDeployStreamTasks(pCtx, pStream, pStatus));
163,132✔
2318

2319
_exit:
163,550✔
2320

2321
  mndReleaseStream(pCtx->pMnode, pStream);
163,550✔
2322

2323
  if (code) {
163,550✔
2324
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2325
  }
2326

2327
  return code;
163,550✔
2328
}
2329

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

2362
_exit:
1,026✔
2363

2364
  if (code) {
1,026✔
2365
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2366
  }
2367

2368
  return code;
1,026✔
2369
}
2370

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

2402
_exit:
2403

2404
  if (code) {
2405
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
2406
  }
2407

2408
  return code;
2409
}
2410
*/
2411

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

UNCOV
2461
_exit:
×
2462

UNCOV
2463
  if (code) {
×
2464
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2465
  }
2466

UNCOV
2467
  return code;
×
2468
}
2469

2470

2471
static int32_t msmLaunchTaskDeployAction(SStmGrpCtx* pCtx, SStmTaskAction* pAction) {
1,026✔
2472
  int32_t code = TSDB_CODE_SUCCESS;
1,026✔
2473
  int32_t lino = 0;
1,026✔
2474
  int64_t streamId = pAction->streamId;
1,026✔
2475
  int64_t taskId = pAction->id.taskId;
1,026✔
2476
  SStreamObj* pStream = NULL;
1,026✔
2477

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

2480
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &pAction->streamId, sizeof(pAction->streamId));
1,026✔
2481
  if (NULL == pStatus) {
1,026✔
2482
    mstsWarn("stream not in streamMap, remain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
2483
    return TSDB_CODE_SUCCESS;
×
2484
  }
2485

2486
  int8_t stopped = atomic_load_8(&pStatus->stopped);
1,026✔
2487
  if (stopped) {
1,026✔
2488
    mstsWarn("stream %s is already stopped %d, ignore task deploy", pStatus->streamName, stopped);
×
2489
    return TSDB_CODE_SUCCESS;
×
2490
  }
2491

2492
  code = mndAcquireStream(pCtx->pMnode, pStatus->streamName, &pStream);
1,026✔
2493
  if (TSDB_CODE_MND_STREAM_NOT_EXIST == code) {
1,026✔
2494
    mstsWarn("stream %s no longer exists, ignore task deploy", pStatus->streamName);
×
2495
    return TSDB_CODE_SUCCESS;
×
2496
  }
2497

2498
  TAOS_CHECK_EXIT(code);
1,026✔
2499

2500
  int8_t userStopped = atomic_load_8(&pStream->userStopped);
1,026✔
2501
  int8_t userDropped = atomic_load_8(&pStream->userDropped);
1,026✔
2502
  if (userStopped || userDropped) {
1,026✔
2503
    mstsWarn("stream %s is stopped %d or removing %d, ignore task deploy", pStatus->streamName, userStopped, userDropped);
×
2504
    goto _exit;
×
2505
  }
2506

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

2530
_exit:
1,026✔
2531

2532
  if (pStream) {
1,026✔
2533
    mndReleaseStream(pCtx->pMnode, pStream);
1,026✔
2534
  }
2535

2536
  if (code) {
1,026✔
2537
    msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
2538
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2539
  }
2540

2541
  return code;
1,026✔
2542
}
2543

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

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

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

2589
  return TSDB_CODE_SUCCESS;
×
2590
}
2591

2592
static int32_t msmRemoveStreamFromMaps(SMnode* pMnode, int64_t streamId) {
406✔
2593
  int32_t code = TSDB_CODE_SUCCESS;
406✔
2594
  int32_t lino = 0;
406✔
2595

2596
  mstsInfo("start to remove stream from maps, current stream num:%d", taosHashGetSize(mStreamMgmt.streamMap));
406✔
2597

2598
  TAOS_CHECK_EXIT(msmSTRemoveStream(streamId, true));
406✔
2599

2600
_exit:
406✔
2601

2602
  if (code) {
406✔
2603
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2604
  } else {
2605
    mstsInfo("end remove stream from maps, current stream num:%d", taosHashGetSize(mStreamMgmt.streamMap));
406✔
2606
  }
2607

2608
  return code;
406✔
2609
}
2610

2611
void msmUndeployStream(SMnode* pMnode, int64_t streamId, char* streamName) {
25,309✔
2612
  int32_t code = TSDB_CODE_SUCCESS;
25,309✔
2613
  int32_t lino = 0;
25,309✔
2614

2615
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
25,309✔
2616
  if (0 == active || MND_STM_STATE_NORMAL != state) {
25,309✔
2617
    mstsError("stream mgmt not available since active:%d state:%d", active, state);
316✔
2618
    return;
316✔
2619
  }
2620

2621
  SStmStatus* pStream = (SStmStatus*)taosHashAcquire(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
24,993✔
2622
  if (NULL == pStream) {
24,993✔
2623
    mstsInfo("stream %s already not in streamMap", streamName);
820✔
2624
    goto _exit;
820✔
2625
  }
2626

2627
  atomic_store_8(&pStream->stopped, 2);
24,173✔
2628

2629
  mstsInfo("set stream %s stopped by user", streamName);
24,173✔
2630

2631
_exit:
×
2632

2633
  taosHashRelease(mStreamMgmt.streamMap, pStream);
24,993✔
2634

2635
  if (code) {
24,993✔
2636
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2637
  }
2638

2639
  return;
24,993✔
2640
}
2641

2642
int32_t msmRecalcStream(SMnode* pMnode, int64_t streamId, STimeWindow* timeRange) {
3,140✔
2643
  int32_t code = TSDB_CODE_SUCCESS;
3,140✔
2644
  int32_t lino = 0;
3,140✔
2645

2646
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
3,140✔
2647
  if (0 == active || MND_STM_STATE_NORMAL != state) {
3,140✔
2648
    mstsError("stream mgmt not available since active:%d state:%d", active, state);
×
2649
    return TSDB_CODE_MND_STREAM_NOT_AVAILABLE;
×
2650
  }
2651

2652
  SStmStatus* pStream = (SStmStatus*)taosHashAcquire(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
3,140✔
2653
  if (NULL == pStream || !STREAM_IS_RUNNING(pStream)) {
3,140✔
2654
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
2655
    mstsInfo("stream still not in streamMap, streamRemains:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
2656
    goto _exit;
×
2657
  }
2658

2659
  TAOS_CHECK_EXIT(mstAppendNewRecalcRange(streamId, pStream, timeRange));
3,140✔
2660

2661
_exit:
3,140✔
2662

2663
  taosHashRelease(mStreamMgmt.streamMap, pStream);
3,140✔
2664

2665
  if (code) {
3,140✔
2666
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2667
  }
2668

2669
  return code;
3,140✔
2670
}
2671

2672
static void msmHandleStreamActions(SStmGrpCtx* pCtx) {
30,554✔
2673
  int32_t code = TSDB_CODE_SUCCESS;
30,554✔
2674
  int32_t lino = 0;
30,554✔
2675
  SStmQNode* pQNode = NULL;
30,554✔
2676

2677
  while (mndStreamActionDequeue(mStreamMgmt.actionQ, &pQNode)) {
195,735✔
2678
    switch (pQNode->type) {
165,181✔
2679
      case STREAM_ACT_DEPLOY:
165,181✔
2680
        if (pQNode->streamAct) {
165,181✔
2681
          mstDebug("start to handle stream deploy action");
164,155✔
2682
          TAOS_CHECK_EXIT(msmLaunchStreamDeployAction(pCtx, &pQNode->action.stream));
164,155✔
2683
        } else {
2684
          mstDebug("start to handle task deploy action");
1,026✔
2685
          TAOS_CHECK_EXIT(msmLaunchTaskDeployAction(pCtx, &pQNode->action.task));
1,026✔
2686
        }
2687
        break;
165,181✔
2688
      default:
×
2689
        break;
×
2690
    }
2691
  }
2692

2693
_exit:
30,554✔
2694

2695
  if (code) {
30,554✔
2696
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2697
  }
2698
}
30,554✔
2699

2700
void msmStopAllStreamsByGrant(int32_t errCode) {
×
2701
  SStmStatus* pStatus = NULL;
×
2702
  void* pIter = NULL;
×
2703
  int64_t streamId = 0;
×
2704
  
2705
  while (true) {
2706
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
×
2707
    if (NULL == pIter) {
×
2708
      break;
×
2709
    }
2710

2711
    pStatus = (SStmStatus*)pIter;
×
2712

2713
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
2714
    atomic_store_8(&pStatus->stopped, 4);
×
2715

2716
    mstsInfo("set stream stopped since %s", tstrerror(errCode));
×
2717
  }
2718
}
×
2719

2720
int32_t msmHandleGrantExpired(SMnode *pMnode, int32_t errCode) {
×
2721
  mstInfo("stream grant expired");
×
2722

2723
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
×
2724
    mstWarn("mnode stream is NOT active, ignore handling");
×
2725
    return errCode;
×
2726
  }
2727

2728
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, true);
×
2729

2730
  msmStopAllStreamsByGrant(errCode);
×
2731

2732
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
×
2733
  
2734
  return errCode;
×
2735
}
2736

2737
static int32_t msmInitStreamDeploy(SStmStreamDeploy* pStream, SStmTaskDeploy* pDeploy) {
1,154,557✔
2738
  int32_t code = TSDB_CODE_SUCCESS;
1,154,557✔
2739
  int32_t lino = 0;
1,154,557✔
2740
  int64_t streamId = pDeploy->task.streamId;
1,154,557✔
2741
  
2742
  switch (pDeploy->task.type) {
1,154,557✔
2743
    case STREAM_READER_TASK:
495,587✔
2744
      if (NULL == pStream->readerTasks) {
495,587✔
2745
        pStream->streamId = streamId;
214,627✔
2746
        pStream->readerTasks = taosArrayInit(20, sizeof(SStmTaskDeploy));
214,627✔
2747
        TSDB_CHECK_NULL(pStream->readerTasks, code, lino, _exit, terrno);
214,627✔
2748
      }
2749
      
2750
      TSDB_CHECK_NULL(taosArrayPush(pStream->readerTasks, pDeploy), code, lino, _exit, terrno);
991,174✔
2751
      break;
495,587✔
2752
    case STREAM_TRIGGER_TASK:
162,398✔
2753
      pStream->streamId = streamId;
162,398✔
2754
      pStream->triggerTask = taosMemoryMalloc(sizeof(SStmTaskDeploy));
162,398✔
2755
      TSDB_CHECK_NULL(pStream->triggerTask, code, lino, _exit, terrno);
162,398✔
2756
      memcpy(pStream->triggerTask, pDeploy, sizeof(SStmTaskDeploy));
162,398✔
2757
      break;
162,398✔
2758
    case STREAM_RUNNER_TASK:
496,572✔
2759
      if (NULL == pStream->runnerTasks) {
496,572✔
2760
        pStream->streamId = streamId;
165,062✔
2761
        pStream->runnerTasks = taosArrayInit(20, sizeof(SStmTaskDeploy));
165,062✔
2762
        TSDB_CHECK_NULL(pStream->runnerTasks, code, lino, _exit, terrno);
165,062✔
2763
      }      
2764
      TSDB_CHECK_NULL(taosArrayPush(pStream->runnerTasks, pDeploy), code, lino, _exit, terrno);
993,144✔
2765
      break;
496,572✔
2766
    default:
×
2767
      break;
×
2768
  }
2769

2770
_exit:
1,154,557✔
2771

2772
  if (code) {
1,154,557✔
2773
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2774
  }
2775

2776
  return code;
1,154,557✔
2777
}
2778

2779
static int32_t msmGrpAddDeployTask(SHashObj* pHash, SStmTaskDeploy* pDeploy) {
1,154,557✔
2780
  int32_t code = TSDB_CODE_SUCCESS;
1,154,557✔
2781
  int32_t lino = 0;
1,154,557✔
2782
  int64_t streamId = pDeploy->task.streamId;
1,154,557✔
2783
  SStreamTask* pTask = &pDeploy->task;
1,154,557✔
2784
  SStmStreamDeploy streamDeploy = {0};
1,154,557✔
2785
  SStmStreamDeploy* pStream = NULL;
1,154,557✔
2786
   
2787
  while (true) {
2788
    pStream = taosHashAcquire(pHash, &streamId, sizeof(streamId));
1,154,557✔
2789
    if (NULL == pStream) {
1,154,557✔
2790
      TAOS_CHECK_EXIT(msmInitStreamDeploy(&streamDeploy, pDeploy));
223,958✔
2791
      code = taosHashPut(pHash, &streamId, sizeof(streamId), &streamDeploy, sizeof(streamDeploy));
223,958✔
2792
      if (TSDB_CODE_SUCCESS == code) {
223,958✔
2793
        goto _exit;
223,958✔
2794
      }
2795

2796
      if (TSDB_CODE_DUP_KEY != code) {
×
2797
        goto _exit;
×
2798
      }    
2799

2800
      tFreeSStmStreamDeploy(&streamDeploy);
×
2801
      continue;
×
2802
    }
2803

2804
    TAOS_CHECK_EXIT(msmInitStreamDeploy(pStream, pDeploy));
930,599✔
2805
    
2806
    break;
930,599✔
2807
  }
2808
  
2809
_exit:
1,154,557✔
2810

2811
  taosHashRelease(pHash, pStream);
1,154,557✔
2812

2813
  if (code) {
1,154,557✔
2814
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2815
  } else {
2816
    msttDebug("task added to GRP deployMap, taskIdx:%d", pTask->taskIdx);
1,154,557✔
2817
  }
2818

2819
  return code;
1,154,557✔
2820
}
2821

2822

2823
int32_t msmGrpAddDeployTasks(SHashObj* pHash, SArray* pTasks, int32_t* deployed) {
154,390✔
2824
  int32_t code = TSDB_CODE_SUCCESS;
154,390✔
2825
  int32_t lino = 0;
154,390✔
2826
  int32_t taskNum = taosArrayGetSize(pTasks);
154,390✔
2827

2828
  for (int32_t i = 0; i < taskNum; ++i) {
1,313,351✔
2829
    SStmTaskToDeployExt* pExt = taosArrayGet(pTasks, i);
1,158,961✔
2830
    if (pExt->deployed) {
1,158,961✔
2831
      continue;
4,404✔
2832
    }
2833

2834
    TAOS_CHECK_EXIT(msmGrpAddDeployTask(pHash, &pExt->deploy));
1,154,557✔
2835
    pExt->deployed = true;
1,154,557✔
2836

2837
    (void)atomic_add_fetch_32(deployed, 1);
1,154,557✔
2838
  }
2839

2840
_exit:
154,390✔
2841

2842
  if (code) {
154,390✔
2843
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2844
  }
2845

2846
  return code;
154,390✔
2847
}
2848

2849
int32_t msmGrpAddDeployVgTasks(SStmGrpCtx* pCtx) {
45,557✔
2850
  int32_t code = TSDB_CODE_SUCCESS;
45,557✔
2851
  int32_t lino = 0;
45,557✔
2852
  int32_t vgNum = taosArrayGetSize(pCtx->pReq->pVgLeaders);
45,557✔
2853
  SStmVgTasksToDeploy* pVg = NULL;
45,557✔
2854
  //int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pCtx->pReq->streamGId);
2855

2856
  mstDebug("start to add stream vgroup tasks deploy");
45,557✔
2857
  
2858
  for (int32_t i = 0; i < vgNum; ++i) {
317,594✔
2859
    int32_t* vgId = taosArrayGet(pCtx->pReq->pVgLeaders, i);
272,037✔
2860

2861
    msmUpdateVgroupUpTs(pCtx, *vgId);
272,037✔
2862

2863
    pVg = taosHashAcquire(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId));
272,037✔
2864
    if (NULL == pVg) {
272,037✔
2865
      continue;
182,242✔
2866
    }
2867

2868
    if (taosRTryLockLatch(&pVg->lock)) {
89,795✔
2869
      continue;
×
2870
    }
2871
    
2872
    if (atomic_load_32(&pVg->deployed) == taosArrayGetSize(pVg->taskList)) {
89,795✔
UNCOV
2873
      taosRUnLockLatch(&pVg->lock);
×
UNCOV
2874
      continue;
×
2875
    }
2876
    
2877
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pVg->taskList, &pVg->deployed));
89,795✔
2878
    taosRUnLockLatch(&pVg->lock);
89,795✔
2879
  }
2880

2881
_exit:
45,557✔
2882

2883
  if (code) {
45,557✔
2884
    if (pVg) {
×
2885
      taosRUnLockLatch(&pVg->lock);
×
2886
    }
2887

2888
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2889
  }
2890

2891
  return code;
45,557✔
2892
}
2893

2894
int32_t msmGrpAddDeploySnodeTasks(SStmGrpCtx* pCtx) {
37,333✔
2895
  int32_t code = TSDB_CODE_SUCCESS;
37,333✔
2896
  int32_t lino = 0;
37,333✔
2897
  SStmSnodeTasksDeploy* pSnode = NULL;
37,333✔
2898
  SStreamHbMsg* pReq = pCtx->pReq;
37,333✔
2899

2900
  mstDebug("start to add stream snode tasks deploy");
37,333✔
2901
  
2902
  pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &pReq->snodeId, sizeof(pReq->snodeId));
37,333✔
2903
  if (NULL == pSnode) {
37,333✔
2904
    return TSDB_CODE_SUCCESS;
3,603✔
2905
  }
2906

2907
  (void)mstWaitLock(&pSnode->lock, false);
33,730✔
2908
  
2909
  if (atomic_load_32(&pSnode->triggerDeployed) < taosArrayGetSize(pSnode->triggerList)) {
33,730✔
2910
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pSnode->triggerList, &pSnode->triggerDeployed));
31,207✔
2911
  }
2912

2913
  if (atomic_load_32(&pSnode->runnerDeployed) < taosArrayGetSize(pSnode->runnerList)) {
33,730✔
2914
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pSnode->runnerList, &pSnode->runnerDeployed));
33,388✔
2915
  }
2916
  
2917
  taosWUnLockLatch(&pSnode->lock);
33,730✔
2918

2919
_exit:
33,730✔
2920

2921
  if (code) {
33,730✔
2922
    if (pSnode) {
×
2923
      taosWUnLockLatch(&pSnode->lock);
×
2924
    }
2925

2926
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2927
  }
2928

2929
  return code;
33,730✔
2930
}
2931

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

2943
_exit:
564,486✔
2944

2945
  if (code) {
564,486✔
2946
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2947
  }
2948

2949
  return code;
564,486✔
2950
}
2951

2952
int32_t msmRspAddStreamsDeploy(SStmGrpCtx* pCtx) {
46,679✔
2953
  int32_t code = TSDB_CODE_SUCCESS;
46,679✔
2954
  int32_t lino = 0;
46,679✔
2955
  int32_t streamNum = taosHashGetSize(pCtx->deployStm);
46,679✔
2956
  void* pIter = NULL;
46,679✔
2957

2958
  mstDebug("start to add group %d deploy streams, streamNum:%d", pCtx->pReq->streamGId, taosHashGetSize(pCtx->deployStm));
46,679✔
2959
  
2960
  pCtx->pRsp->deploy.streamList = taosArrayInit(streamNum, sizeof(SStmStreamDeploy));
46,679✔
2961
  TSDB_CHECK_NULL(pCtx->pRsp->deploy.streamList, code, lino, _exit, terrno);
46,679✔
2962

2963
  while (1) {
223,958✔
2964
    pIter = taosHashIterate(pCtx->deployStm, pIter);
270,637✔
2965
    if (pIter == NULL) {
270,637✔
2966
      break;
46,679✔
2967
    }
2968
    
2969
    SStmStreamDeploy *pDeploy = (SStmStreamDeploy *)pIter;
223,958✔
2970
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->deploy.streamList, pDeploy), code, lino, _exit, terrno);
447,916✔
2971

2972
    int64_t streamId = pDeploy->streamId;
223,958✔
2973
    mstsDebug("stream DEPLOY added to dnode %d hb rsp, readerTasks:%zu, triggerTask:%d, runnerTasks:%zu", 
223,958✔
2974
        pCtx->pReq->dnodeId, taosArrayGetSize(pDeploy->readerTasks), pDeploy->triggerTask ? 1 : 0, taosArrayGetSize(pDeploy->runnerTasks));
2975

2976
    mstClearSStmStreamDeploy(pDeploy);
223,958✔
2977
    
2978
    TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(pDeploy->streamId, pCtx->currTs));
223,958✔
2979
  }
2980
  
2981
_exit:
46,679✔
2982

2983
  if (pIter) {
46,679✔
2984
    taosHashCancelIterate(pCtx->deployStm, pIter);
×
2985
  }
2986

2987
  if (code) {
46,679✔
2988
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2989
  }
2990
  
2991
  return code;
46,679✔
2992
}
2993

2994
void msmCleanDeployedVgTasks(SArray* pVgLeaders) {
45,557✔
2995
  int32_t code = TSDB_CODE_SUCCESS;
45,557✔
2996
  int32_t lino = 0;
45,557✔
2997
  int32_t vgNum = taosArrayGetSize(pVgLeaders);
45,557✔
2998
  SStmVgTasksToDeploy* pVg = NULL;
45,557✔
2999
  
3000
  for (int32_t i = 0; i < vgNum; ++i) {
317,594✔
3001
    int32_t* vgId = taosArrayGet(pVgLeaders, i);
272,037✔
3002
    pVg = taosHashAcquire(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId));
272,037✔
3003
    if (NULL == pVg) {
272,037✔
3004
      continue;
182,242✔
3005
    }
3006

3007
    if (taosWTryLockLatch(&pVg->lock)) {
89,795✔
3008
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
×
3009
      continue;
×
3010
    }
3011
    
3012
    if (atomic_load_32(&pVg->deployed) <= 0) {
89,795✔
3013
      taosWUnLockLatch(&pVg->lock);
×
3014
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
×
3015
      continue;
×
3016
    }
3017

3018
    int32_t taskNum = taosArrayGetSize(pVg->taskList);
89,795✔
3019
    if (atomic_load_32(&pVg->deployed) == taskNum) {
89,795✔
3020
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeployVgTaskNum, taskNum);
89,403✔
3021
      taosArrayDestroyEx(pVg->taskList, mstDestroySStmTaskToDeployExt);
89,403✔
3022
      pVg->taskList = NULL;
89,403✔
3023
      TAOS_UNUSED(taosHashRemove(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId)));
89,403✔
3024
      taosWUnLockLatch(&pVg->lock);
89,403✔
3025
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
89,403✔
3026
      continue;
89,403✔
3027
    }
3028

3029
    for (int32_t m = taskNum - 1; m >= 0; --m) {
3,328✔
3030
      SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, m);
2,936✔
3031
      if (!pExt->deployed) {
2,936✔
3032
        continue;
×
3033
      }
3034

3035
      mstDestroySStmTaskToDeployExt(pExt);
2,936✔
3036

3037
      taosArrayRemove(pVg->taskList, m);
2,936✔
3038
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeployVgTaskNum, 1);
2,936✔
3039
    }
3040
    atomic_store_32(&pVg->deployed, 0);
392✔
3041
    taosWUnLockLatch(&pVg->lock);
392✔
3042
    taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
392✔
3043
  }
3044

3045
_exit:
45,557✔
3046

3047
  if (code) {
45,557✔
3048
    if (pVg) {
×
3049
      taosWUnLockLatch(&pVg->lock);
×
3050
    }
3051

3052
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3053
  }
3054
}
45,557✔
3055

3056
void msmCleanDeployedSnodeTasks (int32_t snodeId) {
37,921✔
3057
  if (!GOT_SNODE(snodeId)) {
37,921✔
3058
    return;
588✔
3059
  }
3060
  
3061
  int32_t code = TSDB_CODE_SUCCESS;
37,333✔
3062
  SStmSnodeTasksDeploy* pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &snodeId, sizeof(snodeId));
37,333✔
3063
  if (NULL == pSnode) {
37,333✔
3064
    return;
3,603✔
3065
  }
3066

3067
  if (taosWTryLockLatch(&pSnode->lock)) {
33,730✔
3068
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
×
3069
    return;
×
3070
  }
3071

3072
  int32_t triggerNum = taosArrayGetSize(pSnode->triggerList);
33,730✔
3073
  int32_t runnerNum = taosArrayGetSize(pSnode->runnerList);
33,730✔
3074
  
3075
  if (atomic_load_32(&pSnode->triggerDeployed) <= 0 && atomic_load_32(&pSnode->runnerDeployed) <= 0) {
33,730✔
3076
    taosWUnLockLatch(&pSnode->lock);
342✔
3077
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
342✔
3078
    return;
342✔
3079
  }
3080

3081
  if (atomic_load_32(&pSnode->triggerDeployed) == triggerNum) {
33,388✔
3082
    (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, triggerNum);
32,825✔
3083
    taosArrayDestroyEx(pSnode->triggerList, mstDestroySStmTaskToDeployExt);
32,825✔
3084
    pSnode->triggerList = NULL;
32,825✔
3085
  }
3086

3087
  if (atomic_load_32(&pSnode->runnerDeployed) == runnerNum) {
33,388✔
3088
    (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, runnerNum);
32,825✔
3089
    taosArrayDestroyEx(pSnode->runnerList, mstDestroySStmTaskToDeployExt);
32,825✔
3090
    pSnode->runnerList = NULL;
32,825✔
3091
  }
3092

3093
  if (NULL == pSnode->triggerList && NULL == pSnode->runnerList) {
33,388✔
3094
    TAOS_UNUSED(taosHashRemove(mStreamMgmt.toDeploySnodeMap, &snodeId, sizeof(snodeId)));
32,825✔
3095
    taosWUnLockLatch(&pSnode->lock);
32,825✔
3096
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
32,825✔
3097
    return;
32,825✔
3098
  }
3099

3100
  if (atomic_load_32(&pSnode->triggerDeployed) > 0 && pSnode->triggerList) {
563✔
3101
    for (int32_t m = triggerNum - 1; m >= 0; --m) {
2,031✔
3102
      SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, m);
1,468✔
3103
      if (!pExt->deployed) {
1,468✔
3104
        continue;
×
3105
      }
3106

3107
      mstDestroySStmTaskToDeployExt(pExt);
1,468✔
3108
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
1,468✔
3109
      taosArrayRemove(pSnode->triggerList, m);
1,468✔
3110
    }
3111
    
3112
    pSnode->triggerDeployed = 0;
563✔
3113
  }
3114

3115
  if (atomic_load_32(&pSnode->runnerDeployed) > 0 && pSnode->runnerList) {
563✔
3116
    for (int32_t m = runnerNum - 1; m >= 0; --m) {
4,283✔
3117
      SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, m);
3,720✔
3118
      if (!pExt->deployed) {
3,720✔
3119
        continue;
×
3120
      }
3121

3122
      mstDestroySStmTaskToDeployExt(pExt);
3,720✔
3123
      (void)atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
3,720✔
3124
      taosArrayRemove(pSnode->runnerList, m);
3,720✔
3125
    }
3126
    
3127
    pSnode->runnerDeployed = 0;
563✔
3128
  }
3129
  
3130
  taosWUnLockLatch(&pSnode->lock);
563✔
3131
  taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
563✔
3132
}
3133

3134
void msmClearStreamToDeployMaps(SStreamHbMsg* pHb) {
17,940,184✔
3135
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
17,940,184✔
3136
    msmCleanDeployedVgTasks(pHb->pVgLeaders);
45,557✔
3137
  }
3138

3139
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0) {
17,940,184✔
3140
    msmCleanDeployedSnodeTasks(pHb->snodeId);
37,921✔
3141
  }
3142
}
17,940,184✔
3143

3144
void msmCleanStreamGrpCtx(SStreamHbMsg* pHb) {
17,940,184✔
3145
  int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pHb->streamGId);
17,940,184✔
3146
  if (mStreamMgmt.tCtx) {
17,940,184✔
3147
    taosHashClear(mStreamMgmt.tCtx[tidx].actionStm[pHb->streamGId]);
17,862,480✔
3148
    taosHashClear(mStreamMgmt.tCtx[tidx].deployStm[pHb->streamGId]);
17,862,480✔
3149
  }
3150
}
17,940,184✔
3151

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

3169
_exit:
218,822✔
3170

3171
  if (code) {
218,822✔
3172
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3173
  }
3174

3175
  return code;
218,822✔
3176
}
3177

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

3194
_exit:
×
3195

3196
  if (code) {
×
3197
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3198
  }
3199

3200
  return code;
×
3201
}
3202

3203

3204

3205
int32_t msmGrpAddActionUndeploy(SStmGrpCtx* pCtx, int64_t streamId, SStreamTask* pTask) {
121,706✔
3206
  int32_t code = TSDB_CODE_SUCCESS;
121,706✔
3207
  int32_t lino = 0;
121,706✔
3208
  int32_t action = STREAM_ACT_UNDEPLOY;
121,706✔
3209
  bool    dropped = false;
121,706✔
3210

3211
  TAOS_CHECK_EXIT(mstIsStreamDropped(pCtx->pMnode, streamId, &dropped));
121,706✔
3212
  mstsDebug("stream dropped: %d", dropped);
121,706✔
3213
  
3214
  SStmAction *pAction = taosHashGet(pCtx->actionStm, &streamId, sizeof(streamId));
121,706✔
3215
  if (pAction) {
121,706✔
3216
    pAction->actions |= action;
88,763✔
3217
    if (NULL == pAction->undeploy.taskList) {
88,763✔
3218
      pAction->undeploy.taskList = taosArrayInit(pCtx->taskNum, POINTER_BYTES);
×
3219
      TSDB_CHECK_NULL(pAction->undeploy.taskList, code, lino, _exit, terrno);
×
3220
    }
3221

3222
    TSDB_CHECK_NULL(taosArrayPush(pAction->undeploy.taskList, &pTask), code, lino, _exit, terrno);
177,526✔
3223
    if (pAction->undeploy.doCheckpoint) {
88,763✔
3224
      pAction->undeploy.doCheckpoint = dropped ? false : true;
20,929✔
3225
    }
3226
    if (!pAction->undeploy.doCleanup) {
88,763✔
3227
      pAction->undeploy.doCleanup = dropped ? true : false;
20,929✔
3228
    }
3229
    
3230
    msttDebug("task append UNDEPLOY action[%d,%d], actions:%x", pAction->undeploy.doCheckpoint, pAction->undeploy.doCleanup, pAction->actions);
88,763✔
3231
  } else {
3232
    SStmAction newAction = {0};
32,943✔
3233
    newAction.actions = action;
32,943✔
3234
    newAction.undeploy.doCheckpoint = dropped ? false : true;
32,943✔
3235
    newAction.undeploy.doCleanup = dropped ? true : false;
32,943✔
3236
    newAction.undeploy.taskList = taosArrayInit(pCtx->taskNum, POINTER_BYTES);
32,943✔
3237
    TSDB_CHECK_NULL(newAction.undeploy.taskList, code, lino, _exit, terrno);
32,943✔
3238
    TSDB_CHECK_NULL(taosArrayPush(newAction.undeploy.taskList, &pTask), code, lino, _exit, terrno);
65,886✔
3239
    TAOS_CHECK_EXIT(taosHashPut(pCtx->actionStm, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
32,943✔
3240
    
3241
    msttDebug("task add UNDEPLOY action[%d,%d]", newAction.undeploy.doCheckpoint, newAction.undeploy.doCleanup);
32,943✔
3242
  }
3243

3244
_exit:
121,706✔
3245

3246
  if (code) {
121,706✔
3247
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3248
  }
3249

3250
  return code;
121,706✔
3251
}
3252

3253
int32_t msmGrpAddActionRecalc(SStmGrpCtx* pCtx, int64_t streamId, SArray* recalcList) {
3,140✔
3254
  int32_t code = TSDB_CODE_SUCCESS;
3,140✔
3255
  int32_t lino = 0;
3,140✔
3256
  int32_t action = STREAM_ACT_RECALC;
3,140✔
3257
  SStmAction newAction = {0};
3,140✔
3258
  
3259
  SStmAction *pAction = taosHashGet(pCtx->actionStm, &streamId, sizeof(streamId));
3,140✔
3260
  if (pAction) {
3,140✔
3261
    pAction->actions |= action;
×
3262
    pAction->recalc.recalcList = recalcList;
×
3263

3264
    mstsDebug("stream append recalc action, listSize:%d, actions:%x", (int32_t)taosArrayGetSize(recalcList), pAction->actions);
×
3265
  } else {
3266
    newAction.actions = action;
3,140✔
3267
    newAction.recalc.recalcList = recalcList;
3,140✔
3268
    
3269
    TAOS_CHECK_EXIT(taosHashPut(pCtx->actionStm, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
3,140✔
3270
    
3271
    mstsDebug("stream add recalc action, listSize:%d", (int32_t)taosArrayGetSize(recalcList));
3,140✔
3272
  }
3273

3274
_exit:
3,140✔
3275

3276
  if (code) {
3,140✔
3277
    mstDestroySStmAction(&newAction);
×
3278
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3279
  }
3280

3281
  return code;
3,140✔
3282
}
3283

3284
bool msmCheckStreamStartCond(int64_t streamId, int32_t snodeId) {
286,204✔
3285
  SStmStatus* pStream = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
286,204✔
3286
  if (NULL == pStream) {
286,204✔
3287
    return false;
×
3288
  }
3289

3290
  if (pStream->triggerTask->id.nodeId != snodeId || STREAM_STATUS_INIT != pStream->triggerTask->status) {
286,204✔
3291
    return false;
×
3292
  }
3293

3294
  int32_t readerNum = taosArrayGetSize(pStream->trigReaders);
286,204✔
3295
  for (int32_t i = 0; i < readerNum; ++i) {
624,326✔
3296
    SStmTaskStatus* pStatus = taosArrayGet(pStream->trigReaders, i);
338,122✔
3297
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
338,122✔
3298
      return false;
×
3299
    }
3300
  }
3301

3302
  readerNum = msmGetTrigOReaderSize(pStream->trigOReaders);
286,204✔
3303
  for (int32_t i = 0; i < readerNum; ++i) {
343,292✔
3304
    SStmTaskStatus* pStatus = msmGetTrigOReader(pStream->trigOReaders, i);
57,088✔
3305
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
57,088✔
3306
      return false;
×
3307
    }
3308
  }
3309

3310
  readerNum = MST_LIST_SIZE(pStream->calcReaders);
286,204✔
3311
  SListNode* pNode = listHead(pStream->calcReaders);
286,204✔
3312
  for (int32_t i = 0; i < readerNum; ++i) {
852,439✔
3313
    SStmTaskStatus* pStatus = (SStmTaskStatus*)pNode->data;
566,235✔
3314
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
566,235✔
3315
      return false;
×
3316
    }
3317
    pNode = TD_DLIST_NODE_NEXT(pNode);
566,235✔
3318
  }
3319

3320
  for (int32_t i = 0; i < pStream->runnerDeploys; ++i) {
924,598✔
3321
    int32_t runnerNum = taosArrayGetSize(pStream->runners[i]);
705,776✔
3322
    for (int32_t m = 0; m < runnerNum; ++m) {
1,362,908✔
3323
      SStmTaskStatus* pStatus = taosArrayGet(pStream->runners[i], m);
724,514✔
3324
      if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
724,514✔
3325
        return false;
67,382✔
3326
      }
3327
    }
3328
  }
3329
  
3330
  return true;
218,822✔
3331
}
3332

3333

3334
void msmHandleTaskAbnormalStatus(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pMsg, SStmTaskStatus* pTaskStatus) {
10,296,982✔
3335
  int32_t code = TSDB_CODE_SUCCESS;
10,296,982✔
3336
  int32_t lino = 0;
10,296,982✔
3337
  int32_t action = 0;
10,296,982✔
3338
  int64_t streamId = pMsg->streamId;
10,296,982✔
3339
  SStreamTask* pTask = (SStreamTask*)pMsg;
10,296,982✔
3340
  int8_t  stopped = 0;
10,296,982✔
3341

3342
  msttDebug("start to handle task abnormal status %d", pTask->status);
10,296,982✔
3343
  
3344
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
10,296,982✔
3345
  if (NULL == pStatus) {
10,296,982✔
3346
    msttInfo("stream no longer exists in streamMap, try to undeploy current task, idx:%d", pMsg->taskIdx);
×
3347
    TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
×
3348
    return;
9,396✔
3349
  }
3350

3351
  stopped = atomic_load_8(&pStatus->stopped);
10,296,982✔
3352
  if (stopped) {
10,296,982✔
3353
    msttInfo("stream stopped %d, try to undeploy current task, idx:%d", stopped, pMsg->taskIdx);
×
3354
    TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
×
3355
    return;
×
3356
  }
3357
  
3358
  switch (pMsg->status) {
10,296,982✔
3359
    case STREAM_STATUS_INIT:      
10,292,679✔
3360
      if (STREAM_TRIGGER_TASK != pMsg->type) {
10,292,679✔
3361
        msttTrace("task status is INIT and not trigger task, ignore it, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
9,865,346✔
3362
        return;
9,865,346✔
3363
      }
3364
      
3365
      if (INT64_MIN == pStatus->lastActionTs) {
427,333✔
3366
        msttDebug("task still not deployed, ignore it, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
×
3367
        return;
×
3368
      }
3369
      
3370
      if ((pCtx->currTs - pStatus->lastActionTs) < STREAM_ACT_MIN_DELAY_MSEC) {
427,333✔
3371
        msttDebug("task wait not enough between actions, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
141,129✔
3372
        return;
141,129✔
3373
      }
3374

3375
      if (STREAM_IS_RUNNING(pStatus)) {
286,204✔
3376
        msttDebug("stream already running, ignore status: %s", gStreamStatusStr[pTask->status]);
×
3377
      } else if (GOT_SNODE(pCtx->pReq->snodeId) && msmCheckStreamStartCond(streamId, pCtx->pReq->snodeId)) {
286,204✔
3378
        TAOS_CHECK_EXIT(msmGrpAddActionStart(pCtx->actionStm, streamId, &pStatus->triggerTask->id));
218,822✔
3379
      }
3380
      break;
286,204✔
3381
    case STREAM_STATUS_FAILED:
4,303✔
3382
      //STREAMTODO ADD ERRCODE HANDLE
3383
      if (STREAM_RUNNER_TASK == pTask->type || STREAM_TRIGGER_TASK == pTask->type) {
4,303✔
3384
        msttWarn("task failed with error:%s, try to undeploy whole stream, idx:%d", tstrerror(pMsg->errorCode),
4,303✔
3385
                 pMsg->taskIdx);
3386
        msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
4,303✔
3387
      } else {
UNCOV
3388
        msttInfo("task failed with error:%s, try to undeploy current task, idx:%d", tstrerror(pMsg->errorCode),
×
3389
                 pMsg->taskIdx);
UNCOV
3390
        TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
×
3391
      }
3392
      break;
4,303✔
3393
    default:
×
3394
      break;
×
3395
  }
3396

3397
_exit:
290,507✔
3398

3399
  if (code) {
290,507✔
3400
    msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
3401
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3402
  }
3403
}
3404

3405
void msmHandleStreamTaskErr(SStmGrpCtx* pCtx, EStmErrType err, SStmTaskStatusMsg* pStatus) {
121,706✔
3406
  int32_t code = TSDB_CODE_SUCCESS;
121,706✔
3407
  int32_t lino = 0;
121,706✔
3408
  SStreamTask* pTask = (SStreamTask*)pStatus;
121,706✔
3409
  int64_t streamId = pStatus->streamId;
121,706✔
3410

3411
  msttInfo("start to handle task error, type: %d", err);
121,706✔
3412

3413
  TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
121,706✔
3414

3415
_exit:
121,706✔
3416

3417
  if (code) {
121,706✔
3418
    // IGNORE STOP STREAM BY ERROR  
3419
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3420
  }
3421
}
121,706✔
3422

3423
void msmChkHandleTriggerOperations(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask, SStmTaskStatus* pStatus) {
3,759,445✔
3424
  int32_t code = TSDB_CODE_SUCCESS;
3,759,445✔
3425
  int32_t lino = 0;
3,759,445✔
3426
  SStmStatus* pStream = (SStmStatus*)pStatus->pStream;
3,759,445✔
3427

3428
  if (1 == atomic_val_compare_exchange_8(&pStream->triggerNeedUpdate, 1, 0)) {
3,759,445✔
3429
    TAOS_CHECK_EXIT(msmGrpAddActionUpdateTrigger(pCtx->actionStm, pTask->streamId));
×
3430
  }
3431
  
3432
  SArray* userRecalcList = NULL;
3,759,445✔
3433
  if (atomic_load_ptr(&pStream->userRecalcList)) {
3,759,445✔
3434
    taosWLockLatch(&pStream->userRecalcLock);
3,140✔
3435
    if (pStream->userRecalcList) {
3,140✔
3436
      userRecalcList = pStream->userRecalcList;
3,140✔
3437
      pStream->userRecalcList = NULL;
3,140✔
3438
    }
3439
    taosWUnLockLatch(&pStream->userRecalcLock);
3,140✔
3440
    
3441
    if (userRecalcList) {
3,140✔
3442
      TAOS_CHECK_EXIT(msmGrpAddActionRecalc(pCtx, pTask->streamId, userRecalcList));
3,140✔
3443
    }
3444
  }
3445

3446
  if (pTask->detailStatus >= 0 && pCtx->pReq->pTriggerStatus) {
3,759,445✔
3447
    (void)mstWaitLock(&pStatus->detailStatusLock, false);
1,878,166✔
3448
    if (NULL == pStatus->detailStatus) {
1,878,166✔
3449
      pStatus->detailStatus = taosMemoryCalloc(1, sizeof(SSTriggerRuntimeStatus));
161,417✔
3450
      if (NULL == pStatus->detailStatus) {
161,417✔
3451
        taosWUnLockLatch(&pStatus->detailStatusLock);
×
3452
        TSDB_CHECK_NULL(pStatus->detailStatus, code, lino, _exit, terrno);
×
3453
      }
3454
    }
3455
    
3456
    memcpy(pStatus->detailStatus, taosArrayGet(pCtx->pReq->pTriggerStatus, pTask->detailStatus), sizeof(SSTriggerRuntimeStatus));
1,878,166✔
3457
    taosWUnLockLatch(&pStatus->detailStatusLock);
1,878,166✔
3458
  }
3459

3460
_exit:
1,881,279✔
3461

3462
  if (code) {
3,759,445✔
3463
    // IGNORE STOP STREAM BY ERROR
3464
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3465
  }
3466
}
3,759,445✔
3467

3468
int32_t msmNormalHandleStatusUpdate(SStmGrpCtx* pCtx) {
965,230✔
3469
  int32_t code = TSDB_CODE_SUCCESS;
965,230✔
3470
  int32_t lino = 0;
965,230✔
3471
  int32_t num = taosArrayGetSize(pCtx->pReq->pStreamStatus);
965,230✔
3472

3473
  mstDebug("NORMAL: start to handle stream group %d tasks status, taskNum:%d", pCtx->pReq->streamGId, num);
965,230✔
3474

3475
  for (int32_t i = 0; i < num; ++i) {
29,609,512✔
3476
    SStmTaskStatusMsg* pTask = taosArrayGet(pCtx->pReq->pStreamStatus, i);
28,644,282✔
3477
    msttDebug("task status %s got on dnode %d, taskIdx:%d", gStreamStatusStr[pTask->status], pCtx->pReq->dnodeId, pTask->taskIdx);
28,644,282✔
3478
    
3479
    SStmTaskStatus** ppStatus = taosHashGet(mStreamMgmt.taskMap, &pTask->streamId, sizeof(pTask->streamId) + sizeof(pTask->taskId));
28,644,282✔
3480
    if (NULL == ppStatus) {
28,644,282✔
3481
      msttWarn("task no longer exists in taskMap, will try to undeploy current task, taskIdx:%d", pTask->taskIdx);
6,264✔
3482
      msmHandleStreamTaskErr(pCtx, STM_ERR_TASK_NOT_EXISTS, pTask);
6,264✔
3483
      continue;
6,264✔
3484
    }
3485

3486
    SStmStatus* pStream = (SStmStatus*)(*ppStatus)->pStream;
28,638,018✔
3487
    int8_t stopped = atomic_load_8(&pStream->stopped);
28,638,018✔
3488
    if (stopped) {
28,638,018✔
3489
      msttWarn("stream already stopped %d, will try to undeploy current task, taskIdx:%d", stopped, pTask->taskIdx);
115,442✔
3490
      msmHandleStreamTaskErr(pCtx, STM_ERR_STREAM_STOPPED, pTask);
115,442✔
3491
      continue;
115,442✔
3492
    }
3493

3494
    if ((pTask->seriousId != (*ppStatus)->id.seriousId) || (pTask->nodeId != (*ppStatus)->id.nodeId)) {
28,522,576✔
3495
      msttInfo("task mismatch with it in taskMap, will try to rm it, current seriousId:%" PRId64 ", nodeId:%d", 
×
3496
          (*ppStatus)->id.seriousId, (*ppStatus)->id.nodeId);
3497
          
3498
      msmHandleStreamTaskErr(pCtx, STM_ERR_TASK_NOT_EXISTS, pTask);
×
3499
      continue;
×
3500
    }
3501

3502
    if ((*ppStatus)->status != pTask->status) {
28,522,576✔
3503
      if (STREAM_STATUS_RUNNING == pTask->status) {
1,998,286✔
3504
        (*ppStatus)->runningStartTs = pCtx->currTs;
846,604✔
3505
      } else if (MST_IS_RUNNER_GETTING_READY(pTask) && STREAM_IS_REDEPLOY_RUNNER((*ppStatus)->flags)) {
1,151,682✔
3506
        if (pStream->triggerTask) {
×
3507
          atomic_store_8(&pStream->triggerNeedUpdate, 1);
×
3508
        }
3509
        
3510
        STREAM_CLR_FLAG((*ppStatus)->flags, STREAM_FLAG_REDEPLOY_RUNNER);
×
3511
      }
3512
    }
3513
    
3514
    (*ppStatus)->errCode = pTask->errorCode;
28,522,576✔
3515
    (*ppStatus)->status = pTask->status;
28,522,576✔
3516
    (*ppStatus)->lastUpTs = pCtx->currTs;
28,522,576✔
3517
    
3518
    if (STREAM_STATUS_RUNNING != pTask->status) {
28,522,576✔
3519
      msmHandleTaskAbnormalStatus(pCtx, pTask, *ppStatus);
10,296,982✔
3520
    }
3521
    
3522
    if (STREAM_TRIGGER_TASK == pTask->type) {
28,522,576✔
3523
      msmChkHandleTriggerOperations(pCtx, pTask, *ppStatus);
3,759,445✔
3524
    }
3525
  }
3526

3527
_exit:
965,230✔
3528

3529
  if (code) {
965,230✔
3530
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3531
  }
3532

3533
  return code;
965,230✔
3534
}
3535

3536
int32_t msmWatchRecordNewTask(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
×
3537
  int32_t code = TSDB_CODE_SUCCESS;
×
3538
  int32_t lino = 0;
×
3539
  int64_t streamId = pTask->streamId;
×
3540
  SStreamObj* pStream = NULL;
×
3541

3542
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3543
  if (NULL == pStatus) {
×
3544
    SStmStatus status = {0};
×
3545
    TAOS_CHECK_EXIT(mndAcquireStreamById(pCtx->pMnode, streamId, &pStream));
×
3546
    TSDB_CHECK_NULL(pStream, code, lino, _exit, TSDB_CODE_MND_STREAM_NOT_EXIST);
×
3547
    if (STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags) || pStream->pCreate->vtableCalc) {
×
3548
      mndReleaseStream(pCtx->pMnode, pStream);
×
3549
      msttDebug("virtual table task ignored, triggerTblType:%d, vtableCalc:%dstatus:%s", 
×
3550
          pStream->pCreate->triggerTblType, pStream->pCreate->vtableCalc, gStreamStatusStr[pTask->status]);
3551
      return code;
×
3552
    }
3553

3554
    TAOS_CHECK_EXIT(msmInitStmStatus(pCtx, &status, pStream, true));
×
3555
    mndReleaseStream(pCtx->pMnode, pStream);
×
3556

3557
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.streamMap, &streamId, sizeof(streamId), &status, sizeof(status)));
×
3558
    pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3559
    TSDB_CHECK_NULL(pStatus, code, lino, _exit, terrno);
×
3560
    msttDebug("stream added to streamMap cause of new task status:%s", gStreamStatusStr[pTask->status]);
×
3561
  }
3562

3563
  SStmTaskStatus* pNewTask = NULL;
×
3564
  switch (pTask->type) {
×
3565
    case STREAM_READER_TASK: {
×
3566
      void* pList = STREAM_IS_TRIGGER_READER(pTask->flags) ? (void*)pStatus->trigReaders : (void*)pStatus->calcReaders;
×
3567
      if (NULL == pList) {
×
3568
        mstsError("%sReader list is NULL", STREAM_IS_TRIGGER_READER(pTask->flags) ? "trig" : "calc");
×
3569
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3570
      }
3571
      int32_t readerSize = STREAM_IS_TRIGGER_READER(pTask->flags) ? pStatus->trigReaderNum : pStatus->calcReaderNum;
×
3572
      if ((STREAM_IS_TRIGGER_READER(pTask->flags) && taosArrayGetSize(pList) >= readerSize) ||
×
3573
          MST_LIST_SIZE((SList*)pList) >= readerSize){
×
3574
        mstsError("%sReader list is already full, size:%d, expSize:%d", STREAM_IS_TRIGGER_READER(pTask->flags) ? "trig" : "calc",
×
3575
            (int32_t)taosArrayGetSize(pList), readerSize);
3576
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3577
      }
3578
      
3579
      SStmTaskStatus taskStatus = {0};
×
3580
      taskStatus.pStream = pStatus;
×
3581
      mstSetTaskStatusFromMsg(pCtx, &taskStatus, pTask);
×
3582
      if (STREAM_IS_TRIGGER_READER(pTask->flags)) {
×
3583
        pNewTask = taosArrayPush(pList, &taskStatus);
×
3584
        TSDB_CHECK_NULL(pNewTask, code, lino, _exit, terrno);
×
3585
      } else {
3586
        TAOS_CHECK_EXIT(tdListAppend(pStatus->calcReaders, &taskStatus));
×
3587
        SListNode* pTailNode = tdListGetTail(pStatus->calcReaders);
×
3588
        QUERY_CHECK_NULL(pTailNode, code, lino, _exit, TSDB_CODE_INTERNAL_ERROR);
×
3589
        pNewTask = (SStmTaskStatus*)pTailNode->data;
×
3590
      }
3591
      
3592
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pNewTask));
×
3593
      TAOS_CHECK_EXIT(msmSTAddToVgroupMapImpl(streamId, pNewTask, STREAM_IS_TRIGGER_READER(pTask->flags)));
×
3594
      break;
×
3595
    }
3596
    case STREAM_TRIGGER_TASK: {
×
3597
      taosMemoryFreeClear(pStatus->triggerTask);
×
3598
      pStatus->triggerTask = taosMemoryCalloc(1, sizeof(*pStatus->triggerTask));
×
3599
      TSDB_CHECK_NULL(pStatus->triggerTask, code, lino, _exit, terrno);
×
3600
      pStatus->triggerTask->pStream = pStatus;
×
3601
      mstSetTaskStatusFromMsg(pCtx, pStatus->triggerTask, pTask);
×
3602
      pNewTask = pStatus->triggerTask;
×
3603

3604
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pNewTask));
×
3605
      TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pNewTask, 0));
×
3606
      break;
×
3607
    }
3608
    case STREAM_RUNNER_TASK:{
×
3609
      if (NULL == pStatus->runners[pTask->deployId]) {
×
3610
        mstsError("deploy %d runner list is NULL", pTask->deployId);
×
3611
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3612
      }
3613
      if (taosArrayGetSize(pStatus->runners[pTask->deployId]) >= pStatus->runnerNum) {
×
3614
        mstsError("deploy %d runner list is already full, size:%d, expSize:%d", pTask->deployId, 
×
3615
            (int32_t)taosArrayGetSize(pStatus->runners[pTask->deployId]), pStatus->runnerNum);
3616
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3617
      }    
3618
      
3619
      SStmTaskStatus taskStatus = {0};
×
3620
      taskStatus.pStream = pStatus;
×
3621
      mstSetTaskStatusFromMsg(pCtx, &taskStatus, pTask);
×
3622
      pNewTask = taosArrayPush(pStatus->runners[pTask->deployId], &taskStatus);
×
3623
      TSDB_CHECK_NULL(pNewTask, code, lino, _exit, terrno);
×
3624

3625
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pNewTask));
×
3626
      TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pNewTask, pTask->deployId));
×
3627
      break;
×
3628
    }
3629
    default: {
×
3630
      msttError("invalid task type:%d in task status", pTask->type);
×
3631
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3632
      break;
×
3633
    }
3634
  }
3635

3636
_exit:
×
3637

3638
  if (code) {
×
3639
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3640
  } else {
3641
    msttDebug("new task recored to taskMap/streamMap, task status:%s", gStreamStatusStr[pTask->status]);
×
3642
  }
3643

3644
  return code;
×
3645
}
3646

3647
int32_t msmWatchHandleStatusUpdate(SStmGrpCtx* pCtx) {
×
3648
  int32_t code = TSDB_CODE_SUCCESS;
×
3649
  int32_t lino = 0;
×
3650
  int32_t num = taosArrayGetSize(pCtx->pReq->pStreamStatus);
×
3651

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

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

3658
    if (pTask->taskId >= mStreamMgmt.lastTaskId) {
×
3659
      mStreamMgmt.lastTaskId = pTask->taskId + 1;
×
3660
    }
3661
    
3662
    SStmTaskStatus** ppStatus = taosHashGet(mStreamMgmt.taskMap, &pTask->streamId, sizeof(pTask->streamId) + sizeof(pTask->taskId));
×
3663
    if (NULL == ppStatus) {
×
3664
      msttInfo("task still not in taskMap, will try to add it, taskIdx:%d", pTask->taskIdx);
×
3665
      
3666
      TAOS_CHECK_EXIT(msmWatchRecordNewTask(pCtx, pTask));
×
3667
      
3668
      continue;
×
3669
    }
3670
    
3671
    (*ppStatus)->status = pTask->status;
×
3672
    (*ppStatus)->lastUpTs = pCtx->currTs;
×
3673
  }
3674

3675
_exit:
×
3676

3677
  if (code) {
×
3678
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3679
  }
3680

3681
  return code;
×
3682
}
3683

3684
void msmRspAddStreamStart(int64_t streamId, SStmGrpCtx* pCtx, int32_t streamNum, SStmAction *pAction) {
218,822✔
3685
  int32_t code = TSDB_CODE_SUCCESS;
218,822✔
3686
  int32_t lino = 0;
218,822✔
3687
  if (NULL == pCtx->pRsp->start.taskList) {
218,822✔
3688
    pCtx->pRsp->start.taskList = taosArrayInit(streamNum, sizeof(SStreamTaskStart));
82,351✔
3689
    TSDB_CHECK_NULL(pCtx->pRsp->start.taskList, code, lino, _exit, terrno);
82,351✔
3690
  }
3691

3692
  SStmTaskId* pId = &pAction->start.triggerId;
218,822✔
3693
  SStreamTaskStart start = {0};
218,822✔
3694
  start.task.type = STREAM_TRIGGER_TASK;
218,822✔
3695
  start.task.streamId = streamId;
218,822✔
3696
  start.task.taskId = pId->taskId;
218,822✔
3697
  start.task.seriousId = pId->seriousId;
218,822✔
3698
  start.task.nodeId = pId->nodeId;
218,822✔
3699
  start.task.taskIdx = pId->taskIdx;
218,822✔
3700

3701
  TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->start.taskList, &start), code, lino, _exit, terrno);
437,644✔
3702
  TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(streamId, pCtx->currTs));
218,822✔
3703

3704
  mstsDebug("stream START added to dnode %d hb rsp, triggerTaskId:%" PRIx64, pId->nodeId, pId->taskId);
218,822✔
3705

3706
  return;
218,822✔
3707

3708
_exit:
×
3709

3710
  mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3711
}
3712

3713

3714
void msmRspAddStreamUndeploy(int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
32,943✔
3715
  int32_t code = TSDB_CODE_SUCCESS;
32,943✔
3716
  int32_t lino = 0;
32,943✔
3717
  int32_t dropNum = taosArrayGetSize(pAction->undeploy.taskList);
32,943✔
3718
  if (NULL == pCtx->pRsp->undeploy.taskList) {
32,943✔
3719
    pCtx->pRsp->undeploy.taskList = taosArrayInit(dropNum, sizeof(SStreamTaskUndeploy));
21,955✔
3720
    TSDB_CHECK_NULL(pCtx->pRsp->undeploy.taskList, code, lino, _exit, terrno);
21,955✔
3721
  }
3722

3723
  SStreamTaskUndeploy undeploy;
32,943✔
3724
  for (int32_t i = 0; i < dropNum; ++i) {
154,649✔
3725
    SStreamTask* pTask = (SStreamTask*)taosArrayGetP(pAction->undeploy.taskList, i);
121,706✔
3726
    undeploy.task = *pTask;
121,706✔
3727
    undeploy.undeployMsg.doCheckpoint = pAction->undeploy.doCheckpoint;
121,706✔
3728
    undeploy.undeployMsg.doCleanup = pAction->undeploy.doCleanup;
121,706✔
3729

3730
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->undeploy.taskList, &undeploy), code, lino, _exit, terrno);
243,412✔
3731
    TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(streamId, pCtx->currTs));
121,706✔
3732

3733
    msttDebug("task UNDEPLOY added to hb rsp, doCheckpoint:%d, doCleanup:%d", undeploy.undeployMsg.doCheckpoint, undeploy.undeployMsg.doCleanup);
121,706✔
3734
  }
3735

3736
  return;
32,943✔
3737

3738
_exit:
×
3739

3740
  mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3741
}
3742

3743
void msmRspAddTriggerUpdate(SMnode * pMnode, int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
×
3744
  int32_t code = TSDB_CODE_SUCCESS;
×
3745
  int32_t lino = 0;
×
3746

3747
  SStmStatus* pStream = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3748
  if (NULL == pStream) {
×
3749
    mstsDebug("stream already not exists in streamMap, ignore trigger update, streamRemain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
3750
    return;
×
3751
  }
3752

3753
  if (NULL == pStream->triggerTask) {
×
3754
    mstsWarn("no triggerTask exists, ignore trigger update, stopped:%d", atomic_load_8(&pStream->stopped));
×
3755
    return;
×
3756
  }
3757

3758
  SStreamMgmtRsp rsp = {0};
×
3759
  rsp.reqId = INT64_MIN;
×
3760
  rsp.header.msgType = STREAM_MSG_UPDATE_RUNNER;
×
3761
  rsp.task.streamId = streamId;
×
3762
  rsp.task.taskId = pStream->triggerTask->id.taskId;
×
3763

3764
  TAOS_CHECK_EXIT(msmBuildTriggerRunnerTargets(pMnode, pStream, streamId, &rsp.cont.runnerList));  
×
3765

3766
  if (NULL == pCtx->pRsp->rsps.rspList) {
×
3767
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
3768
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
×
3769
  }
3770

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

3773
_exit:
×
3774

3775
  if (code) {
×
3776
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3777
  } else {
3778
    mstsDebug("trigger update rsp added, runnerNum:%d", (int32_t)taosArrayGetSize(rsp.cont.runnerList));
×
3779
  }
3780
}
3781

3782
void msmRspAddUserRecalc(SMnode * pMnode, int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
3,140✔
3783
  int32_t code = TSDB_CODE_SUCCESS;
3,140✔
3784
  int32_t lino = 0;
3,140✔
3785

3786
  SStmStatus* pStream = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
3,140✔
3787
  if (NULL == pStream) {
3,140✔
3788
    mstsDebug("stream already not exists in streamMap, ignore trigger update, streamRemain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
3789
    return;
×
3790
  }
3791

3792
  if (NULL == pStream->triggerTask) {
3,140✔
3793
    mstsWarn("no triggerTask exists, ignore trigger update, stopped:%d", atomic_load_8(&pStream->stopped));
×
3794
    return;
×
3795
  }
3796

3797
  SStreamMgmtRsp rsp = {0};
3,140✔
3798
  rsp.reqId = INT64_MIN;
3,140✔
3799
  rsp.header.msgType = STREAM_MSG_USER_RECALC;
3,140✔
3800
  rsp.task.streamId = streamId;
3,140✔
3801
  rsp.task.taskId = pStream->triggerTask->id.taskId;
3,140✔
3802
  TSWAP(rsp.cont.recalcList, pAction->recalc.recalcList);
3,140✔
3803

3804
  if (NULL == pCtx->pRsp->rsps.rspList) {
3,140✔
3805
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
2,760✔
3806
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
2,760✔
3807
  }
3808

3809
  TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), code, lino, _exit, terrno);
6,280✔
3810

3811
_exit:
3,140✔
3812

3813
  if (code) {
3,140✔
3814
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3815
  } else {
3816
    mstsDebug("user recalc rsp added, recalcNum:%d", (int32_t)taosArrayGetSize(rsp.cont.recalcList));
3,140✔
3817
  }
3818
}
3819

3820

3821
int32_t msmHandleHbPostActions(SStmGrpCtx* pCtx) {
106,711✔
3822
  int32_t code = TSDB_CODE_SUCCESS;
106,711✔
3823
  int32_t lino = 0;
106,711✔
3824
  void* pIter = NULL;
106,711✔
3825
  int32_t streamNum = taosHashGetSize(pCtx->actionStm);
106,711✔
3826

3827
  mstDebug("start to handle stream group %d post actions", pCtx->pReq->streamGId);
106,711✔
3828

3829
  while (1) {
254,905✔
3830
    pIter = taosHashIterate(pCtx->actionStm, pIter);
361,616✔
3831
    if (pIter == NULL) {
361,616✔
3832
      break;
106,711✔
3833
    }
3834

3835
    int64_t* pStreamId = taosHashGetKey(pIter, NULL);
254,905✔
3836
    SStmAction *pAction = (SStmAction *)pIter;
254,905✔
3837
    
3838
    if (STREAM_ACT_UNDEPLOY & pAction->actions) {
254,905✔
3839
      msmRspAddStreamUndeploy(*pStreamId, pCtx, pAction);
32,943✔
3840
      continue;
32,943✔
3841
    }
3842

3843
    if (STREAM_ACT_UPDATE_TRIGGER & pAction->actions) {
221,962✔
3844
      msmRspAddTriggerUpdate(pCtx->pMnode, *pStreamId, pCtx, pAction);
×
3845
    }
3846

3847
    if (STREAM_ACT_RECALC & pAction->actions) {
221,962✔
3848
      msmRspAddUserRecalc(pCtx->pMnode, *pStreamId, pCtx, pAction);
3,140✔
3849
    }
3850

3851
    if (STREAM_ACT_START & pAction->actions) {
221,962✔
3852
      msmRspAddStreamStart(*pStreamId, pCtx, streamNum, pAction);
218,822✔
3853
    }
3854
  }
3855
  
3856
_exit:
106,711✔
3857

3858
  if (pIter) {
106,711✔
3859
    taosHashCancelIterate(pCtx->actionStm, pIter);
×
3860
  }
3861

3862
  if (code) {
106,711✔
3863
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3864
  }
3865

3866
  return code;
106,711✔
3867
}
3868

3869
int32_t msmCheckUpdateDnodeTs(SStmGrpCtx* pCtx) {
17,862,480✔
3870
  int32_t  code = TSDB_CODE_SUCCESS;
17,862,480✔
3871
  int32_t  lino = 0;
17,862,480✔
3872
  int64_t* lastTs = NULL;
17,862,480✔
3873
  bool     noExists = false;
17,862,480✔
3874

3875
  while (true) {
3876
    lastTs = taosHashGet(mStreamMgmt.dnodeMap, &pCtx->pReq->dnodeId, sizeof(pCtx->pReq->dnodeId));
18,340,162✔
3877
    if (NULL == lastTs) {
18,340,162✔
3878
      if (noExists) {
623,978✔
3879
        mstWarn("Got unknown dnode %d hb msg, may be dropped", pCtx->pReq->dnodeId);
146,296✔
3880
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NODE_NOT_EXISTS);
146,296✔
3881
      }
3882

3883
      noExists = true;
477,682✔
3884
      TAOS_CHECK_EXIT(msmSTAddDnodesToMap(pCtx->pMnode));
477,682✔
3885
      
3886
      continue;
477,682✔
3887
    }
3888

3889
    while (true) {
×
3890
      int64_t lastTsValue = atomic_load_64(lastTs);
17,716,184✔
3891
      if (pCtx->currTs > lastTsValue) {
17,716,184✔
3892
        if (lastTsValue == atomic_val_compare_exchange_64(lastTs, lastTsValue, pCtx->currTs)) {
17,715,024✔
3893
          mstDebug("dnode %d lastUpTs updated", pCtx->pReq->dnodeId);
17,715,024✔
3894
          return code;
17,715,024✔
3895
        }
3896

3897
        continue;
×
3898
      }
3899

3900
      return code;
1,160✔
3901
    }
3902

3903
    break;
3904
  }
3905

3906
_exit:
146,296✔
3907

3908
  if (code) {
146,296✔
3909
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
146,296✔
3910
  }
3911

3912
  return code;  
146,296✔
3913
}
3914

3915
void msmWatchCheckStreamMap(SStmGrpCtx* pCtx) {
×
3916
  SStmStatus* pStatus = NULL;
×
3917
  int32_t trigReaderNum = 0;
×
3918
  int32_t calcReaderNum = 0;
×
3919
  int32_t runnerNum = 0;
×
3920
  int64_t streamId = 0;
×
3921
  void* pIter = NULL;
×
3922
  while (true) {
3923
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
×
3924
    if (NULL == pIter) {
×
3925
      return;
×
3926
    }
3927

3928
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
3929
    pStatus = (SStmStatus*)pIter;
×
3930

3931
    if (NULL == pStatus->triggerTask) {
×
3932
      mstsWarn("no trigger task recored, deployTimes:%" PRId64, pStatus->deployTimes);
×
3933
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
3934
      continue;
×
3935
    }
3936
    
3937
    trigReaderNum = taosArrayGetSize(pStatus->trigReaders);
×
3938
    if (pStatus->trigReaderNum != trigReaderNum) {
×
3939
      mstsWarn("trigReaderNum %d mis-match with expected %d", trigReaderNum, pStatus->trigReaderNum);
×
3940
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
3941
      continue;
×
3942
    }
3943

3944
    calcReaderNum = MST_LIST_SIZE(pStatus->calcReaders);
×
3945
    if (pStatus->calcReaderNum != calcReaderNum) {
×
3946
      mstsWarn("calcReaderNum %d mis-match with expected %d", calcReaderNum, pStatus->calcReaderNum);
×
3947
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
3948
      continue;
×
3949
    }
3950

3951
    for (int32_t i = 0; i < pStatus->runnerDeploys; ++i) {
×
3952
      runnerNum = taosArrayGetSize(pStatus->runners[i]);
×
3953
      if (runnerNum != pStatus->runnerNum) {
×
3954
        mstsWarn("runner deploy %d runnerNum %d mis-match with expected %d", i, runnerNum, pStatus->runnerNum);
×
3955
        msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
3956
        continue;
×
3957
      }
3958
    }
3959
  }
3960
}
3961

3962
int32_t msmWatchHandleEnding(SStmGrpCtx* pCtx, bool watchError) {
343✔
3963
  int32_t code = TSDB_CODE_SUCCESS;
343✔
3964
  int32_t lino = 0;
343✔
3965
  int32_t minVal = watchError ? 0 : 1;
343✔
3966

3967
  if (0 != atomic_val_compare_exchange_8(&mStreamMgmt.watch.ending, 0, 1)) {
343✔
3968
    return code;
×
3969
  }
3970

3971
  while (atomic_load_32(&mStreamMgmt.watch.processing) > minVal) {
343✔
3972
    (void)sched_yield();
×
3973
  }
3974

3975
  if (watchError) {
343✔
3976
    taosHashClear(mStreamMgmt.vgroupMap);
×
3977
    taosHashClear(mStreamMgmt.snodeMap);
×
3978
    taosHashClear(mStreamMgmt.taskMap);
×
3979
    taosHashClear(mStreamMgmt.streamMap);
×
3980
    mstInfo("watch error happends, clear all maps");
×
3981
    goto _exit;
×
3982
  }
3983

3984
  if (0 == atomic_load_8(&mStreamMgmt.watch.taskRemains)) {
343✔
3985
    mstInfo("no stream tasks remain during watch state");
343✔
3986
    goto _exit;
343✔
3987
  }
3988

3989
  msmWatchCheckStreamMap(pCtx);
×
3990

3991
_exit:
343✔
3992

3993
  mStreamMgmt.lastTaskId += 100000;
343✔
3994

3995
  mstInfo("watch state end, new taskId begin from:%" PRIx64, mStreamMgmt.lastTaskId);
343✔
3996

3997
  msmSetInitRuntimeState(MND_STM_STATE_NORMAL);
343✔
3998

3999
  if (code) {
343✔
4000
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4001
  }
4002

4003
  return code;
343✔
4004
}
4005

4006

4007
int32_t msmWatchHandleHbMsg(SStmGrpCtx* pCtx) {
14,104✔
4008
  int32_t code = TSDB_CODE_SUCCESS;
14,104✔
4009
  int32_t lino = 0;
14,104✔
4010
  SStreamHbMsg* pReq = pCtx->pReq;
14,104✔
4011

4012
  (void)atomic_add_fetch_32(&mStreamMgmt.watch.processing, 1);
14,104✔
4013
  
4014
  if (atomic_load_8(&mStreamMgmt.watch.ending)) {
14,104✔
4015
    goto _exit;
×
4016
  }
4017

4018
  TAOS_CHECK_EXIT(msmCheckUpdateDnodeTs(pCtx));
14,104✔
4019
  if (GOT_SNODE(pReq->snodeId)) {
14,104✔
4020
    TAOS_CHECK_EXIT(msmUpdateSnodeUpTs(pCtx));
2,016✔
4021
  }
4022

4023
  if (taosArrayGetSize(pReq->pStreamStatus) > 0) {
14,104✔
4024
    atomic_store_8(&mStreamMgmt.watch.taskRemains, 1);
×
4025
    TAOS_CHECK_EXIT(msmWatchHandleStatusUpdate(pCtx));
×
4026
  }
4027

4028
  if ((pCtx->currTs - MND_STREAM_GET_LAST_TS(STM_EVENT_ACTIVE_BEGIN)) > MST_SHORT_ISOLATION_DURATION) {
14,104✔
4029
    TAOS_CHECK_EXIT(msmWatchHandleEnding(pCtx, false));
343✔
4030
  }
4031

4032
_exit:
14,104✔
4033

4034
  atomic_sub_fetch_32(&mStreamMgmt.watch.processing, 1);
14,104✔
4035
  
4036
  if (code) {
14,104✔
4037
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4038

4039
    (void)msmWatchHandleEnding(pCtx, true);
×
4040
  }
4041

4042
  return code;
14,104✔
4043
}
4044

4045
int32_t msmGetTrigOReaderSize(SArray* pOReaders) {
5,382,061✔
4046
  int32_t listSize = taosArrayGetSize(pOReaders);
5,382,061✔
4047
  int32_t totalSize = 0;
5,382,061✔
4048
  
4049
  for (int32_t i = 0; i < listSize; ++i) {
6,348,821✔
4050
    SArray* pList = taosArrayGetP(pOReaders, i);
966,760✔
4051
    totalSize += taosArrayGetSize(pList);
966,760✔
4052
  }
4053

4054
  return totalSize;
5,382,061✔
4055
}
4056

4057
SStmTaskStatus* msmGetTrigOReader(SArray* pOReaders, int32_t idx) {
610,488✔
4058
  SArray* pList = taosArrayGetP(pOReaders, idx / MST_ORIGINAL_READER_LIST_SIZE);
610,488✔
4059
  if (NULL == pList) {
610,488✔
4060
    return NULL;
×
4061
  }
4062

4063
  return (SStmTaskStatus*)taosArrayGet(pList, idx % MST_ORIGINAL_READER_LIST_SIZE);
610,488✔
4064
}
4065

4066

4067
int32_t msmEnsureGetOReaderList(int64_t streamId, SStmStatus* pStatus, SArray** ppRes) {
57,088✔
4068
  int32_t code = TSDB_CODE_SUCCESS;
57,088✔
4069
  int32_t lino = 0;
57,088✔
4070

4071
  if (NULL == pStatus->trigOReaders) {
57,088✔
4072
    pStatus->trigOReaders = taosArrayInit(10, POINTER_BYTES);
49,417✔
4073
    TSDB_CHECK_NULL(pStatus->trigOReaders, code, lino, _exit, terrno);
49,417✔
4074
  }
4075

4076
  while (true) {
49,417✔
4077
    SArray** ppOReaderList = taosArrayGetLast(pStatus->trigOReaders);
106,505✔
4078

4079
    if (NULL == ppOReaderList || (*ppOReaderList)->size >= (*ppOReaderList)->capacity) {
106,505✔
4080
      SArray* pOReaderList = taosArrayInit(MST_ORIGINAL_READER_LIST_SIZE, sizeof(SStmTaskStatus));
49,417✔
4081
      TSDB_CHECK_NULL(pOReaderList, code, lino, _exit, terrno);
49,417✔
4082

4083
      TSDB_CHECK_NULL(taosArrayPush(pStatus->trigOReaders, &pOReaderList), code, lino, _exit, terrno);
98,834✔
4084
      continue;
49,417✔
4085
    }
4086

4087
    *ppRes = *ppOReaderList;
57,088✔
4088
    break;
57,088✔
4089
  }
4090

4091
_exit:
57,088✔
4092

4093
  if (code) {
57,088✔
4094
    mstsError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4095
  }
4096

4097
  return code;
57,088✔
4098
}
4099

4100
int32_t msmCheckDeployTrigReader(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStmTaskStatusMsg* pTask, int32_t vgId, int32_t vgNum) {
66,748✔
4101
  int32_t code = TSDB_CODE_SUCCESS;
66,748✔
4102
  int32_t lino = 0;
66,748✔
4103
  bool    readerExists = false;
66,748✔
4104
  int64_t streamId = pTask->streamId;
66,748✔
4105

4106
  int32_t readerNum = taosArrayGetSize(pStatus->trigReaders);
66,748✔
4107
  for (int32_t i = 0; i < readerNum; ++i) {
139,316✔
4108
    SStmTaskStatus* pReader = (SStmTaskStatus*)taosArrayGet(pStatus->trigReaders, i);
82,228✔
4109
    if (pReader->id.nodeId == vgId) {
82,228✔
4110
      readerExists = true;
9,660✔
4111
      break;
9,660✔
4112
    }
4113
  }
4114

4115
  if (!readerExists) {
66,748✔
4116
    SArray* pReaderList = NULL;
57,088✔
4117
    TAOS_CHECK_EXIT(msmEnsureGetOReaderList(streamId, pStatus, &pReaderList));
57,088✔
4118
    
4119
    SStmTaskStatus* pState = taosArrayReserve(pReaderList, 1);
57,088✔
4120
    TAOS_CHECK_EXIT(msmTDAddSingleTrigReader(pCtx, pState, vgId, pStatus, streamId));
57,088✔
4121
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pState));
57,088✔
4122
    TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, NULL, pState, true));
57,088✔
4123
  }
4124

4125
_exit:
9,660✔
4126

4127
  if (code) {
66,748✔
4128
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4129
  }
4130

4131
  return code;
66,748✔
4132
}
4133

4134
int32_t msmDeployTriggerOrigReader(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
58,507✔
4135
  int32_t code = TSDB_CODE_SUCCESS, finalCode = TSDB_CODE_SUCCESS;
58,507✔
4136
  int32_t lino = 0;
58,507✔
4137
  int32_t vgId = 0;
58,507✔
4138
  int64_t streamId = pTask->streamId;
58,507✔
4139
  SArray* pTbs = pTask->pMgmtReq->cont.pReqs;
58,507✔
4140
  int32_t tbNum = taosArrayGetSize(pTbs);
58,507✔
4141
  SStreamDbTableName* pName = NULL;
58,507✔
4142
  SSHashObj* pDbVgroups = NULL;
58,507✔
4143
  SStreamMgmtRsp rsp = {0};
58,507✔
4144
  rsp.reqId = pTask->pMgmtReq->reqId;
58,507✔
4145
  rsp.header.msgType = STREAM_MSG_ORIGTBL_READER_INFO;
58,507✔
4146
  int32_t iter = 0;
58,507✔
4147
  void* p = NULL;
58,507✔
4148
  SSHashObj* pVgs = NULL;
58,507✔
4149
  SStreamMgmtReq* pMgmtReq = NULL;
58,507✔
4150
  int8_t stopped = 0;
58,507✔
4151

4152
  if (NULL == pCtx->pRsp->rsps.rspList) {
58,507✔
4153
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
4154
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, finalCode, lino, _final, terrno);
×
4155
  }
4156
  
4157
  TSWAP(pTask->pMgmtReq, pMgmtReq);
58,507✔
4158
  rsp.task = *(SStreamTask*)pTask;
58,507✔
4159

4160
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
58,507✔
4161
  if (NULL == pStatus) {
58,507✔
4162
    mstsError("stream not deployed, remainStreams:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
4163
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_RUNNING);
×
4164
  }
4165

4166
  if (rsp.reqId == pStatus->lastTrigMgmtReqId) {
58,507✔
4167
    mstsDebug("duplicated trigger oreader deploy msg, will ignore it, reqId %" PRId64, rsp.reqId);
×
4168
    goto _exit;
×
4169
  }
4170

4171
  atomic_store_64(&pStatus->lastTrigMgmtReqId, rsp.reqId); 
58,507✔
4172

4173
  stopped = atomic_load_8(&pStatus->stopped);
58,507✔
4174
  if (stopped) {
58,507✔
4175
    msttInfo("stream stopped %d, ignore deploy trigger reader, vgId:%d", stopped, vgId);
×
4176
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_STOPPED);
×
4177
  }
4178

4179
  if (tbNum <= 0) {
58,507✔
4180
    mstsWarn("empty table list in origReader req, array:%p", pTbs);
×
4181
    goto _exit;
×
4182
  }
4183

4184
  TAOS_CHECK_EXIT(mstBuildDBVgroupsMap(pCtx->pMnode, &pDbVgroups));
58,507✔
4185
  rsp.cont.vgIds = taosArrayInit(tbNum, sizeof(int32_t));
58,507✔
4186
  TSDB_CHECK_NULL(rsp.cont.vgIds, code, lino, _exit, terrno);
58,507✔
4187

4188
  pVgs = tSimpleHashInit(tbNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
58,507✔
4189
  TSDB_CHECK_NULL(pVgs, code, lino, _exit, terrno);
58,507✔
4190
  
4191
  for (int32_t i = 0; i < tbNum; ++i) {
233,016✔
4192
    pName = (SStreamDbTableName*)taosArrayGet(pTbs, i);
174,509✔
4193
    TAOS_CHECK_EXIT(mstGetTableVgId(pDbVgroups, pName->dbFName, pName->tbName, &vgId));
174,509✔
4194
    TSDB_CHECK_NULL(taosArrayPush(rsp.cont.vgIds, &vgId), code, lino, _exit, terrno);
349,018✔
4195
    TAOS_CHECK_EXIT(tSimpleHashPut(pVgs, &vgId, sizeof(vgId), &vgId, sizeof(vgId)));
174,509✔
4196
  }
4197

4198
  int32_t vgNum = tSimpleHashGetSize(pVgs);
58,507✔
4199
  while (true) {
4200
    p = tSimpleHashIterate(pVgs, p, &iter);
125,255✔
4201
    if (NULL == p) {
125,255✔
4202
      break;
58,507✔
4203
    }
4204
    
4205
    TAOS_CHECK_EXIT(msmCheckDeployTrigReader(pCtx, pStatus, pTask, *(int32_t*)p, vgNum));
66,748✔
4206
  }
4207
  
4208
  vgNum = msmGetTrigOReaderSize(pStatus->trigOReaders);
58,507✔
4209
  rsp.cont.readerList = taosArrayInit(vgNum, sizeof(SStreamTaskAddr));
58,507✔
4210
  TSDB_CHECK_NULL(rsp.cont.readerList, code, lino, _exit, terrno);
58,507✔
4211

4212
  SStreamTaskAddr addr;
58,507✔
4213
  for (int32_t i = 0; i < vgNum; ++i) {
115,595✔
4214
    SStmTaskStatus* pOTask = msmGetTrigOReader(pStatus->trigOReaders, i);
57,088✔
4215
    addr.taskId = pOTask->id.taskId;
57,088✔
4216
    addr.nodeId = pOTask->id.nodeId;
57,088✔
4217
    addr.epset = mndGetVgroupEpsetById(pCtx->pMnode, pOTask->id.nodeId);
57,088✔
4218
    TSDB_CHECK_NULL(taosArrayPush(rsp.cont.readerList, &addr), code, lino, _exit, terrno);
114,176✔
4219
    mstsDebug("the %dth otrigReader src added to trigger's virtual orig readerList, TASK:%" PRIx64 " nodeId:%d", i, addr.taskId, addr.nodeId);
57,088✔
4220
  }
4221

4222
_exit:
58,507✔
4223

4224
  tFreeSStreamMgmtReq(pMgmtReq);
58,507✔
4225
  taosMemoryFree(pMgmtReq);
58,507✔
4226

4227
  tSimpleHashCleanup(pVgs);
58,507✔
4228
  mstDestroyDbVgroupsHash(pDbVgroups);
58,507✔
4229

4230
  if (code) {
58,507✔
4231
    rsp.code = code;
×
4232
    
4233
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
×
4234

4235
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4236
  } else {
4237
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
117,014✔
4238
  }
4239

4240
_final:
58,507✔
4241

4242
  if (finalCode) {
58,507✔
4243
    tFreeSStreamMgmtRsp(&rsp);
×
4244
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code)); 
×
4245
    msmHandleStreamTaskErr(pCtx, STM_ERR_PROCESSING_ERR, pTask);
×
4246
  }
4247

4248
  return finalCode;
58,507✔
4249
}
4250

4251
int32_t msmGetCalcScanFromList(int64_t streamId, SArray* pList, int64_t uid, SStreamCalcScan** ppRes) {
2,299✔
4252
  int32_t num = taosArrayGetSize(pList);
2,299✔
4253
  SStreamCalcScan* pScan = NULL;
2,299✔
4254
  int32_t code = TSDB_CODE_SUCCESS, lino = 0;
2,299✔
4255
  int64_t planUid = 0;
2,299✔
4256
  for (int32_t i = 0; i < num; ++i) {
2,299✔
4257
    pScan = (SStreamCalcScan*)taosArrayGet(pList, i);
2,299✔
4258
    TAOS_CHECK_EXIT(mstGetScanUidFromPlan(streamId, pScan->scanPlan, &planUid));
2,299✔
4259
    if (0 != planUid && planUid == uid) {
2,299✔
4260
      *ppRes = pScan;
2,299✔
4261
      break;
2,299✔
4262
    }
4263
  }
4264

4265
_exit:
2,299✔
4266

4267
  if (code) {
2,299✔
4268
    mstsError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
4269
  }
4270

4271
  return code;
2,299✔
4272
}
4273

4274
int32_t msmCheckDeployCalcReader(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStmTaskStatusMsg* pTask, int32_t vgId, int64_t uid, SStreamTaskAddr* pAddr) {
2,299✔
4275
  int32_t code = TSDB_CODE_SUCCESS;
2,299✔
4276
  int32_t lino = 0;
2,299✔
4277
  bool    readerExists = false;
2,299✔
4278
  int64_t streamId = pTask->streamId;
2,299✔
4279
  SListNode* pNode = listHead(pStatus->calcReaders);
2,299✔
4280
  SStmTaskStatus* pReader = NULL;
2,299✔
4281
  int32_t taskIdx = 0;
2,299✔
4282

4283
  int32_t readerNum = MST_LIST_SIZE(pStatus->calcReaders);
2,299✔
4284
  for (int32_t i = 0; i < readerNum; ++i, pNode = TD_DLIST_NODE_NEXT(pNode)) {
21,318✔
4285
    pReader = (SStmTaskStatus*)pNode->data;
19,019✔
4286
    if (pReader->id.nodeId == vgId && pReader->id.uid == uid) {
19,019✔
4287
      readerExists = true;
×
4288
      pAddr->taskId = pReader->id.taskId;
×
4289
      break;
×
4290
    }
4291
  }
4292

4293
  if (!readerExists) {
2,299✔
4294
    if (NULL == pStatus->calcReaders) {
2,299✔
4295
      pStatus->calcReaders = tdListNew(sizeof(SStmTaskStatus));
×
4296
      TSDB_CHECK_NULL(pStatus->calcReaders, code, lino, _exit, terrno);
×
4297
      taskIdx = 0;
×
4298
    } else {
4299
      pNode = listTail(pStatus->calcReaders);
2,299✔
4300
      pReader = (SStmTaskStatus*)pNode->data;
2,299✔
4301
      taskIdx = pReader->id.taskIdx + 1;
2,299✔
4302
    }
4303

4304
    SStreamCalcScan* pScan = NULL;
2,299✔
4305
    TAOS_CHECK_EXIT(msmGetCalcScanFromList(streamId, pStatus->pCreate->calcScanPlanList, uid, &pScan));
2,299✔
4306
    TSDB_CHECK_NULL(pScan, code, lino, _exit, TSDB_CODE_STREAM_INTERNAL_ERROR);
2,299✔
4307
    pReader = tdListReserve(pStatus->calcReaders);
2,299✔
4308
    TAOS_CHECK_EXIT(msmTDAddSingleCalcReader(pCtx, pReader, taskIdx, vgId, pScan->scanPlan, pStatus, streamId));
2,299✔
4309
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, NULL, pReader));
2,299✔
4310
    TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, NULL, pReader, false));
2,299✔
4311
    pAddr->taskId = pReader->id.taskId;
2,299✔
4312
  }
4313

4314
  pAddr->epset = mndGetVgroupEpsetById(pCtx->pMnode, vgId);
2,299✔
4315
  pAddr->nodeId = vgId;
2,299✔
4316

4317
_exit:
2,299✔
4318

4319
  if (code) {
2,299✔
4320
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4321
  }
4322

4323
  return code;
2,299✔
4324
}
4325

4326

4327
int32_t msmDeployRunnerOrigReader(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
2,299✔
4328
  int32_t code = TSDB_CODE_SUCCESS, finalCode = TSDB_CODE_SUCCESS;
2,299✔
4329
  int32_t lino = 0;
2,299✔
4330
  int32_t vgId = 0;
2,299✔
4331
  int64_t streamId = pTask->streamId;
2,299✔
4332
  SArray* pReqs = pTask->pMgmtReq->cont.pReqs;
2,299✔
4333
  int32_t reqNum = taosArrayGetSize(pReqs);
2,299✔
4334
  SStreamOReaderDeployReq* pReq = NULL;
2,299✔
4335
  SStreamOReaderDeployRsp* pRsp = NULL;
2,299✔
4336
  SStreamMgmtRsp rsp = {0};
2,299✔
4337
  rsp.reqId = pTask->pMgmtReq->reqId;
2,299✔
4338
  rsp.header.msgType = STREAM_MSG_RUNNER_ORIGTBL_READER;
2,299✔
4339
  SStreamMgmtReq* pMgmtReq = NULL;
2,299✔
4340
  int8_t stopped = 0;
2,299✔
4341
  int32_t vgNum = 0;
2,299✔
4342
  SStreamTaskAddr* pAddr = NULL;
2,299✔
4343

4344
  if (NULL == pCtx->pRsp->rsps.rspList) {
2,299✔
4345
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
4346
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, finalCode, lino, _final, terrno);
×
4347
  }
4348
  
4349
  TSWAP(pTask->pMgmtReq, pMgmtReq);
2,299✔
4350
  rsp.task = *(SStreamTask*)pTask;
2,299✔
4351

4352
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
2,299✔
4353
  if (NULL == pStatus) {
2,299✔
4354
    mstsError("stream not deployed, remainStreams:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
4355
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_RUNNING);
×
4356
  }
4357

4358
  stopped = atomic_load_8(&pStatus->stopped);
2,299✔
4359
  if (stopped) {
2,299✔
4360
    msttInfo("stream stopped %d, ignore deploy trigger reader, vgId:%d", stopped, vgId);
×
4361
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_STOPPED);
×
4362
  }
4363

4364
  if (reqNum <= 0) {
2,299✔
4365
    mstsWarn("empty req list in origReader req, array:%p", pReqs);
×
4366
    goto _exit;
×
4367
  }
4368

4369
  rsp.cont.execRspList = taosArrayInit_s(sizeof(SStreamOReaderDeployRsp), reqNum);
2,299✔
4370
  TSDB_CHECK_NULL(rsp.cont.execRspList, code, lino, _exit, terrno);
2,299✔
4371

4372
  for (int32_t i = 0; i < reqNum; ++i) {
4,598✔
4373
    pReq = (SStreamOReaderDeployReq*)taosArrayGet(pReqs, i);
2,299✔
4374
    pRsp = (SStreamOReaderDeployRsp*)taosArrayGet(rsp.cont.execRspList, i);
2,299✔
4375
    pRsp->execId = pReq->execId;
2,299✔
4376
    vgNum = taosArrayGetSize(pReq->vgIds);
2,299✔
4377
    pRsp->vgList = taosArrayInit_s(sizeof(SStreamTaskAddr), vgNum);
2,299✔
4378
    TSDB_CHECK_NULL(pRsp->vgList, code, lino, _exit, terrno);
2,299✔
4379
    
4380
    for (int32_t n = 0; n < vgNum; ++n) {
4,598✔
4381
      vgId = *(int32_t*)taosArrayGet(pReq->vgIds, n);
2,299✔
4382
      pAddr = taosArrayGet(pRsp->vgList, n);
2,299✔
4383
      TAOS_CHECK_EXIT(msmCheckDeployCalcReader(pCtx, pStatus, pTask, vgId, pReq->uid, pAddr));
2,299✔
4384
    }
4385
  }
4386

4387
_exit:
2,299✔
4388

4389
  tFreeSStreamMgmtReq(pMgmtReq);
2,299✔
4390
  taosMemoryFree(pMgmtReq);
2,299✔
4391

4392
  if (code) {
2,299✔
4393
    rsp.code = code;
×
4394
    
4395
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
×
4396
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4397
  } else {
4398
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), finalCode, lino, _final, terrno);
4,598✔
4399
  }
4400

4401

4402
_final:
2,299✔
4403

4404
  if (finalCode) {
2,299✔
4405
    tFreeSStreamMgmtRsp(&rsp);
×
4406
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code)); 
×
4407
    msmHandleStreamTaskErr(pCtx, STM_ERR_PROCESSING_ERR, pTask);
×
4408
  }
4409

4410
  return finalCode;
2,299✔
4411
}
4412

4413

4414
int32_t msmHandleTaskMgmtReq(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
60,806✔
4415
  int32_t code = TSDB_CODE_SUCCESS;
60,806✔
4416
  int32_t lino = 0;
60,806✔
4417

4418
  switch (pTask->pMgmtReq->type) {
60,806✔
4419
    case STREAM_MGMT_REQ_TRIGGER_ORIGTBL_READER:
58,507✔
4420
      msmDeployTriggerOrigReader(pCtx, pTask);
58,507✔
4421
      break;
58,507✔
4422
    case STREAM_MGMT_REQ_RUNNER_ORIGTBL_READER:
2,299✔
4423
      msmDeployRunnerOrigReader(pCtx, pTask);
2,299✔
4424
      break;
2,299✔
4425
    default:
×
4426
      msttError("Invalid mgmtReq type:%d", pTask->pMgmtReq->type);
×
4427
      code = TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
4428
      break;
×
4429
  }
4430

4431
_exit:
60,806✔
4432

4433
  if (code) {
60,806✔
4434
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4435
  }
4436

4437
  return code;
60,806✔
4438
}
4439

4440
int32_t msmHandleStreamRequests(SStmGrpCtx* pCtx) {
16,021✔
4441
  int32_t code = TSDB_CODE_SUCCESS;
16,021✔
4442
  int32_t lino = 0;
16,021✔
4443
  SStreamHbMsg* pReq = pCtx->pReq;
16,021✔
4444
  SStmTaskStatusMsg* pTask = NULL;
16,021✔
4445
  
4446
  int32_t reqNum = taosArrayGetSize(pReq->pStreamReq);
16,021✔
4447
  if (reqNum > 0 && NULL == pCtx->pRsp->rsps.rspList) {
16,021✔
4448
    pCtx->pRsp->rsps.rspList = taosArrayInit(reqNum, sizeof(SStreamMgmtRsp));
16,021✔
4449
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
16,021✔
4450
  }
4451
  
4452
  for (int32_t i = 0; i < reqNum; ++i) {
76,827✔
4453
    int32_t idx = *(int32_t*)taosArrayGet(pReq->pStreamReq, i);
60,806✔
4454
    pTask = (SStmTaskStatusMsg*)taosArrayGet(pReq->pStreamStatus, idx);
60,806✔
4455
    if (NULL == pTask) {
60,806✔
4456
      mstError("idx %d is NULL, reqNum:%d", idx, reqNum);
×
4457
      continue;
×
4458
    }
4459

4460
    if (NULL == pTask->pMgmtReq) {
60,806✔
4461
      msttError("idx %d without mgmtReq", idx);
×
4462
      continue;
×
4463
    }
4464

4465
    TAOS_CHECK_EXIT(msmHandleTaskMgmtReq(pCtx, pTask));
60,806✔
4466
  }
4467

4468
_exit:
16,021✔
4469

4470
  if (code) {
16,021✔
4471
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4472
  }
4473

4474
  return code;
16,021✔
4475
}
4476

4477
int32_t msmNormalHandleHbMsg(SStmGrpCtx* pCtx) {
17,848,376✔
4478
  int32_t code = TSDB_CODE_SUCCESS;
17,848,376✔
4479
  int32_t lino = 0;
17,848,376✔
4480
  SStreamHbMsg* pReq = pCtx->pReq;
17,848,376✔
4481

4482
  TAOS_CHECK_EXIT(msmCheckUpdateDnodeTs(pCtx));
17,848,376✔
4483
  if (GOT_SNODE(pReq->snodeId)) {
17,702,080✔
4484
    TAOS_CHECK_EXIT(msmUpdateSnodeUpTs(pCtx));
1,142,715✔
4485
  }
4486
  
4487
  if (atomic_load_64(&mStreamMgmt.actionQ->qRemainNum) > 0 && 0 == taosWTryLockLatch(&mStreamMgmt.actionQLock)) {
17,702,080✔
4488
    msmHandleStreamActions(pCtx);
30,554✔
4489
    taosWUnLockLatch(&mStreamMgmt.actionQLock);
30,554✔
4490
  }
4491

4492
  if (taosArrayGetSize(pReq->pStreamReq) > 0 && mstWaitLock(&mStreamMgmt.actionQLock, false)) {
17,702,080✔
4493
    code = msmHandleStreamRequests(pCtx);
16,021✔
4494
    taosWUnLockLatch(&mStreamMgmt.actionQLock);
16,021✔
4495
    TAOS_CHECK_EXIT(code);
16,021✔
4496
  }
4497

4498
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
17,702,080✔
4499
    TAOS_CHECK_EXIT(msmGrpAddDeployVgTasks(pCtx));
45,557✔
4500
  } else {
4501
    TAOS_CHECK_EXIT(msmUpdateVgroupsUpTs(pCtx));
17,656,523✔
4502
  }
4503

4504
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0 && GOT_SNODE(pReq->snodeId)) {
17,702,080✔
4505
    TAOS_CHECK_EXIT(msmGrpAddDeploySnodeTasks(pCtx));
37,333✔
4506
  }
4507

4508
  if (taosHashGetSize(pCtx->deployStm) > 0) {
17,702,080✔
4509
    TAOS_CHECK_EXIT(msmRspAddStreamsDeploy(pCtx));
46,679✔
4510
  }
4511

4512
  if (taosArrayGetSize(pReq->pStreamStatus) > 0) {
17,702,080✔
4513
    TAOS_CHECK_EXIT(msmNormalHandleStatusUpdate(pCtx));
965,230✔
4514
  }
4515

4516
  if (taosHashGetSize(pCtx->actionStm) > 0) {
17,702,080✔
4517
    TAOS_CHECK_EXIT(msmHandleHbPostActions(pCtx));
106,711✔
4518
  }
4519

4520
_exit:
17,702,080✔
4521

4522
  if (code) {
17,848,376✔
4523
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
146,296✔
4524
  }
4525

4526
  return code;
17,848,376✔
4527
}
4528

4529
void msmEncodeStreamHbRsp(int32_t code, SRpcHandleInfo *pRpcInfo, SMStreamHbRspMsg* pRsp, SRpcMsg* pMsg) {
17,940,184✔
4530
  int32_t lino = 0;
17,940,184✔
4531
  int32_t tlen = 0;
17,940,184✔
4532
  void   *buf = NULL;
17,940,184✔
4533

4534
  if (TSDB_CODE_SUCCESS != code) {
17,940,184✔
4535
    goto _exit;
146,296✔
4536
  }
4537

4538
  tEncodeSize(tEncodeStreamHbRsp, pRsp, tlen, code);
17,793,888✔
4539
  if (code < 0) {
17,793,888✔
4540
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(code));
×
4541
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
4542
  }
4543

4544
  buf = rpcMallocCont(tlen + sizeof(SStreamMsgGrpHeader));
17,793,888✔
4545
  if (buf == NULL) {
17,793,888✔
4546
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(terrno));
×
4547
    TAOS_CHECK_EXIT(terrno);    
×
4548
  }
4549

4550
  ((SStreamMsgGrpHeader *)buf)->streamGid = pRsp->streamGId;
17,793,888✔
4551
  void *abuf = POINTER_SHIFT(buf, sizeof(SStreamMsgGrpHeader));
17,793,888✔
4552

4553
  SEncoder encoder;
17,792,206✔
4554
  tEncoderInit(&encoder, abuf, tlen);
17,793,888✔
4555
  if ((code = tEncodeStreamHbRsp(&encoder, pRsp)) < 0) {
17,793,888✔
4556
    rpcFreeCont(buf);
×
4557
    buf = NULL;
×
4558
    tEncoderClear(&encoder);
×
4559
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(code));
×
4560
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
4561
  }
4562
  tEncoderClear(&encoder);
17,793,888✔
4563

4564
_exit:
17,940,184✔
4565

4566
  pMsg->code = code;
17,940,184✔
4567
  pMsg->info = *pRpcInfo;
17,940,184✔
4568
  if (TSDB_CODE_SUCCESS == code) {
17,940,184✔
4569
    pMsg->contLen = tlen + sizeof(SStreamMsgGrpHeader);
17,793,888✔
4570
    pMsg->pCont = buf;
17,793,888✔
4571
  }
4572
}
17,940,184✔
4573

4574

4575
int32_t msmHandleStreamHbMsg(SMnode* pMnode, int64_t currTs, SStreamHbMsg* pHb, SRpcMsg *pReq, SRpcMsg* pRspMsg) {
17,940,184✔
4576
  int32_t code = TSDB_CODE_SUCCESS;
17,940,184✔
4577
  SMStreamHbRspMsg rsp = {0};
17,940,184✔
4578
  rsp.streamGId = pHb->streamGId;
17,940,184✔
4579

4580
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, true);
17,940,184✔
4581

4582
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
17,940,184✔
4583
    mstWarn("mnode stream become NOT active, ignore stream hb from dnode %d streamGid %d", pHb->dnodeId, pHb->streamGId);
77,704✔
4584
    goto _exit;
77,704✔
4585
  }
4586

4587
  int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pHb->streamGId);
17,862,480✔
4588
  SStmGrpCtx* pCtx = &mStreamMgmt.tCtx[tidx].grpCtx[pHb->streamGId];
17,862,480✔
4589

4590
  pCtx->tidx = tidx;
17,862,480✔
4591
  pCtx->pMnode = pMnode;
17,862,480✔
4592
  pCtx->currTs = currTs;
17,862,480✔
4593
  pCtx->pReq = pHb;
17,862,480✔
4594
  pCtx->pRsp = &rsp;
17,862,480✔
4595
  pCtx->deployStm = mStreamMgmt.tCtx[pCtx->tidx].deployStm[pHb->streamGId];
17,862,480✔
4596
  pCtx->actionStm = mStreamMgmt.tCtx[pCtx->tidx].actionStm[pHb->streamGId];
17,862,480✔
4597
  
4598
  switch (atomic_load_8(&mStreamMgmt.state)) {
17,862,480✔
4599
    case MND_STM_STATE_WATCH:
14,104✔
4600
      code = msmWatchHandleHbMsg(pCtx);
14,104✔
4601
      break;
14,104✔
4602
    case MND_STM_STATE_NORMAL:
17,848,376✔
4603
      code = msmNormalHandleHbMsg(pCtx);
17,848,376✔
4604
      break;
17,848,376✔
4605
    default:
×
4606
      mstError("Invalid stream state: %d", mStreamMgmt.state);
×
4607
      code = TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
4608
      break;
×
4609
  }
4610

4611
_exit:
17,940,184✔
4612

4613
  msmEncodeStreamHbRsp(code, &pReq->info, &rsp, pRspMsg);
17,940,184✔
4614

4615
  msmCleanStreamGrpCtx(pHb);
17,940,184✔
4616
  msmClearStreamToDeployMaps(pHb);
17,940,184✔
4617

4618
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
17,940,184✔
4619
  
4620
  tFreeSMStreamHbRspMsg(&rsp);
17,940,184✔
4621

4622
  return code;
17,940,184✔
4623
}
4624

4625
void msmHandleBecomeLeader(SMnode *pMnode) {
368,571✔
4626
  if (tsDisableStream) {
368,571✔
4627
    return;
×
4628
  }
4629

4630
  mstInfo("start to process mnode become leader");
368,571✔
4631

4632
  int32_t code = 0;
368,571✔
4633
  streamAddVnodeLeader(MNODE_HANDLE);
368,571✔
4634
  
4635
  taosWLockLatch(&mStreamMgmt.runtimeLock);
368,571✔
4636
  msmDestroyRuntimeInfo(pMnode);
368,571✔
4637
  code = msmInitRuntimeInfo(pMnode);
368,571✔
4638
  taosWUnLockLatch(&mStreamMgmt.runtimeLock);
368,571✔
4639

4640
  if (TSDB_CODE_SUCCESS == code) {
368,571✔
4641
    atomic_store_8(&mStreamMgmt.active, 1);
368,571✔
4642
  }
4643

4644
  mstInfo("mnode stream mgmt active:%d", atomic_load_8(&mStreamMgmt.active));
368,571✔
4645
}
4646

4647
void msmHandleBecomeNotLeader(SMnode *pMnode) {  
456,294✔
4648
  if (tsDisableStream) {
456,294✔
4649
    return;
×
4650
  }
4651

4652
  mstInfo("start to process mnode become not leader");
456,294✔
4653

4654
  streamRemoveVnodeLeader(MNODE_HANDLE);
456,294✔
4655

4656
  if (atomic_val_compare_exchange_8(&mStreamMgmt.active, 1, 0)) {
456,294✔
4657
    taosWLockLatch(&mStreamMgmt.runtimeLock);
368,571✔
4658
    msmDestroyRuntimeInfo(pMnode);
368,571✔
4659
    mStreamMgmt.stat.inactiveTimes++;
368,571✔
4660
    taosWUnLockLatch(&mStreamMgmt.runtimeLock);
368,571✔
4661
  }
4662
}
4663

4664

4665
static void msmRedeployStream(int64_t streamId, SStmStatus* pStatus) {
×
4666
  if (1 == atomic_val_compare_exchange_8(&pStatus->stopped, 1, 0)) {
×
4667
    mstsInfo("try to reset and redeploy stream, deployTimes:%" PRId64, pStatus->deployTimes);
×
4668
    mstPostStreamAction(mStreamMgmt.actionQ, streamId, pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
×
4669
  } else {
4670
    mstsWarn("stream stopped %d already changed", atomic_load_8(&pStatus->stopped));
×
4671
  }
4672
}
×
4673

4674
static bool msmCheckStreamAssign(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
6,866✔
4675
  int32_t code = TSDB_CODE_SUCCESS;
6,866✔
4676
  int32_t lino = 0;
6,866✔
4677
  SStreamObj* pStream = pObj;
6,866✔
4678
  SSnodeObj* pSnode = p1;
6,866✔
4679
  SArray** ppRes = p2;
6,866✔
4680

4681
  if (pStream->mainSnodeId == pSnode->id) {
6,866✔
4682
    if (NULL == *ppRes) {
4,481✔
4683
      int32_t streamNum = sdbGetSize(pMnode->pSdb, SDB_STREAM);
853✔
4684
      *ppRes = taosArrayInit(streamNum, POINTER_BYTES);
853✔
4685
      TSDB_CHECK_NULL(*ppRes, code, lino, _exit, terrno);
853✔
4686
    }
4687

4688
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &pStream), code, lino, _exit, terrno);
8,962✔
4689
  }
4690

4691
  return true;
6,866✔
4692

4693
_exit:
×
4694

4695
  if (code) {
×
4696
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4697
  }  
4698

4699
  *(int32_t*)p3 = code;
×
4700

4701
  return false;
×
4702
}
4703

4704

4705
int32_t msmCheckSnodeReassign(SMnode *pMnode, SSnodeObj* pSnode, SArray** ppRes) {
36,201✔
4706
  int32_t code = TSDB_CODE_SUCCESS;
36,201✔
4707
  int32_t lino = 0;
36,201✔
4708
  
4709
  sdbTraverse(pMnode->pSdb, SDB_STREAM, msmCheckStreamAssign, pSnode, ppRes, &code);
36,201✔
4710
  TAOS_CHECK_EXIT(code);
36,201✔
4711

4712
  int32_t streamNum = taosArrayGetSize(*ppRes);
36,201✔
4713
  if (streamNum > 0 && 0 == pSnode->replicaId) {
36,201✔
4714
    mstError("snode %d has no replica while %d streams assigned", pSnode->id, streamNum);
190✔
4715
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_SNODE_IN_USE);
190✔
4716
  }
4717

4718
  //STREAMTODO CHECK REPLICA UPDATED OR NOT
4719

4720
_exit:
36,201✔
4721

4722
  if (code) {
36,201✔
4723
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
190✔
4724
  }  
4725

4726
  return code;
36,201✔
4727
}
4728

4729
static bool msmCheckLoopStreamSdb(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
441,966✔
4730
  SStreamObj* pStream = pObj;
441,966✔
4731
  int64_t streamId = pStream->pCreate->streamId;
441,966✔
4732
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
441,966✔
4733
  SStmCheckStatusCtx* pCtx = (SStmCheckStatusCtx*)p1;
441,966✔
4734
  int8_t userDropped = atomic_load_8(&pStream->userDropped), userStopped = atomic_load_8(&pStream->userStopped);
441,966✔
4735
  
4736
  if ((userDropped || userStopped) && (NULL == pStatus)) {
441,966✔
4737
    mstsDebug("stream userDropped %d userStopped %d and not in streamMap, ignore it", userDropped, userStopped);
380✔
4738
    return true;
380✔
4739
  }
4740
  
4741
  if (pStatus && !MST_STM_PASS_ISOLATION(pStream, pStatus)) {
441,586✔
4742
    mstsDebug("stream not pass isolation time, updateTime:%" PRId64 ", lastActionTs:%" PRId64 ", currentTs %" PRId64 ", ignore check it", 
303,291✔
4743
        pStream->updateTime, pStatus->lastActionTs, mStreamMgmt.hCtx.currentTs);
4744
    return true;
303,291✔
4745
  }
4746

4747
  if (NULL == pStatus && !MST_STM_STATIC_PASS_SHORT_ISOLATION(pStream)) {
138,295✔
4748
    mstsDebug("stream not pass static isolation time, updateTime:%" PRId64 ", currentTs %" PRId64 ", ignore check it", 
38,609✔
4749
        pStream->updateTime, mStreamMgmt.hCtx.currentTs);
4750
    return true;
38,609✔
4751
  }  
4752

4753
  if (pStatus) {
99,686✔
4754
    if (userDropped || userStopped || MST_IS_USER_STOPPED(atomic_load_8(&pStatus->stopped))) {
99,073✔
4755
      (void)msmRemoveStreamFromMaps(pMnode, streamId);
×
4756
    }
4757

4758
    return true;
99,073✔
4759
  }
4760

4761
  mstPostStreamAction(mStreamMgmt.actionQ, streamId, pStream->pCreate->name, NULL, false, STREAM_ACT_DEPLOY);
613✔
4762

4763
  return true;
613✔
4764
}
4765

4766
void msmCheckLoopStreamMap(SMnode *pMnode) {
36,950✔
4767
  SStmStatus* pStatus = NULL;
36,950✔
4768
  void* pIter = NULL;
36,950✔
4769
  int8_t stopped = 0;
36,950✔
4770
  int64_t streamId = 0;
36,950✔
4771
  
4772
  while (true) {
4773
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
249,612✔
4774
    if (NULL == pIter) {
249,612✔
4775
      break;
36,950✔
4776
    }
4777

4778
    pStatus = (SStmStatus*)pIter;
212,662✔
4779

4780
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
212,662✔
4781
    stopped = atomic_load_8(&pStatus->stopped);
212,662✔
4782
    if (MST_IS_USER_STOPPED(stopped)) {
212,662✔
4783
      mstsDebug("stream already stopped by user, deployTimes:%" PRId64, pStatus->deployTimes);
406✔
4784
      (void)msmRemoveStreamFromMaps(pMnode, streamId);
406✔
4785
      continue;
406✔
4786
    }
4787

4788
    if (!sdbCheckExists(pMnode->pSdb, SDB_STREAM, pStatus->streamName)) {
212,256✔
4789
      mstsDebug("stream already not exists, deployTimes:%" PRId64, pStatus->deployTimes);
×
4790
      (void)msmRemoveStreamFromMaps(pMnode, *(int64_t*)taosHashGetKey(pIter, NULL));
×
4791
      continue;
×
4792
    }
4793

4794
    if (MST_IS_ERROR_STOPPED(stopped)) {
212,256✔
4795
      if (mStreamMgmt.hCtx.currentTs < pStatus->fatalRetryTs) {
11,593✔
4796
        mstsDebug("stream already stopped by error %s, retried times:%" PRId64 ", next time not reached, currTs:%" PRId64 ", nextRetryTs:%" PRId64,
7,602✔
4797
            tstrerror(pStatus->fatalError), pStatus->fatalRetryTimes, mStreamMgmt.hCtx.currentTs, pStatus->fatalRetryTs);
4798
            
4799
        MND_STREAM_SET_LAST_TS(STM_EVENT_STM_TERR, mStreamMgmt.hCtx.currentTs);
7,602✔
4800
        continue;
7,602✔
4801
      }
4802

4803
      mstPostStreamAction(mStreamMgmt.actionQ, *(int64_t*)taosHashGetKey(pIter, NULL), pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
3,991✔
4804
      continue;
3,991✔
4805
    }
4806

4807
    if (MST_IS_GRANT_STOPPED(stopped) && TSDB_CODE_SUCCESS == grantCheckExpire(TSDB_GRANT_STREAMS)) {
200,663✔
4808
      mstPostStreamAction(mStreamMgmt.actionQ, *(int64_t*)taosHashGetKey(pIter, NULL), pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
×
4809
      continue;
×
4810
    }
4811
  }
4812
}
36,950✔
4813

4814
void msmCheckStreamsStatus(SMnode *pMnode) {
291,565✔
4815
  SStmCheckStatusCtx ctx = {0};
291,565✔
4816

4817
  mstDebug("start to check streams status, currTs:%" PRId64, mStreamMgmt.hCtx.currentTs);
291,565✔
4818
  
4819
  if (MST_READY_FOR_SDB_LOOP()) {
291,565✔
4820
    mstDebug("ready to check sdb loop, lastLoopSdbTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_SDB].ts);
54,193✔
4821
    sdbTraverse(pMnode->pSdb, SDB_STREAM, msmCheckLoopStreamSdb, &ctx, NULL, NULL);
54,193✔
4822
    MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_SDB, mStreamMgmt.hCtx.currentTs);
54,193✔
4823
  }
4824

4825
  if (MST_READY_FOR_MAP_LOOP()) {
291,565✔
4826
    mstDebug("ready to check map loop, lastLoopMapTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_MAP].ts);
36,950✔
4827
    msmCheckLoopStreamMap(pMnode);
36,950✔
4828
    MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_MAP, mStreamMgmt.hCtx.currentTs);
36,950✔
4829
  }
4830
}
291,565✔
4831

4832
void msmCheckTaskListStatus(int64_t streamId, SStmTaskStatus** pList, int32_t taskNum) {
3,012,953✔
4833
  for (int32_t i = 0; i < taskNum; ++i) {
6,165,474✔
4834
    SStmTaskStatus* pTask = *(pList + i);
3,152,521✔
4835

4836
    if (atomic_load_8(&((SStmStatus*)pTask->pStream)->stopped)) {
3,152,521✔
4837
      continue;
56,931✔
4838
    }
4839
    
4840
    if (!MST_PASS_ISOLATION(pTask->lastUpTs, 1)) {
3,096,346✔
4841
      continue;
3,095,320✔
4842
    }
4843

4844
    int64_t noUpTs = mStreamMgmt.hCtx.currentTs - pTask->lastUpTs;
1,026✔
4845
    if (STREAM_RUNNER_TASK == pTask->type || STREAM_TRIGGER_TASK == pTask->type) {
1,026✔
4846
      mstsWarn("%s TASK:%" PRIx64 " status not updated for %" PRId64 "ms, will try to redeploy it", 
×
4847
          gStreamTaskTypeStr[pTask->type], pTask->id.taskId, noUpTs);
4848
          
4849
      msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_TASK_LOST, mStreamMgmt.hCtx.currentTs);
×
4850
      break;
×
4851
    }
4852

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

4856
    int64_t newSid = atomic_add_fetch_64(&pTask->id.seriousId, 1);
1,026✔
4857
    mstsDebug("task %" PRIx64 " SID updated to %" PRIx64, pTask->id.taskId, newSid);
1,026✔
4858

4859
    SStmTaskAction task = {0};
1,026✔
4860
    task.streamId = streamId;
1,026✔
4861
    task.id = pTask->id;
1,026✔
4862
    task.flag = pTask->flags;
1,026✔
4863
    task.type = pTask->type;
1,026✔
4864
    
4865
    mstPostTaskAction(mStreamMgmt.actionQ, &task, STREAM_ACT_DEPLOY);
1,026✔
4866
  }
4867
}
3,012,953✔
4868

4869
void msmCheckVgroupStreamStatus(SHashObj* pStreams) {
119,833✔
4870
  void* pIter = NULL;
119,833✔
4871
  SStmVgStreamStatus* pVg = NULL;
119,833✔
4872
  int64_t streamId = 0;
119,833✔
4873
  
4874
  while (true) {
1,238,462✔
4875
    pIter = taosHashIterate(pStreams, pIter);
1,358,295✔
4876
    if (NULL == pIter) {
1,358,295✔
4877
      break;
119,833✔
4878
    }
4879

4880
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
1,238,462✔
4881
    pVg = (SStmVgStreamStatus*)pIter;
1,238,462✔
4882

4883
    int32_t taskNum = taosArrayGetSize(pVg->trigReaders);
1,238,462✔
4884
    if (taskNum > 0) {
1,238,462✔
4885
      msmCheckTaskListStatus(streamId, taosArrayGet(pVg->trigReaders, 0), taskNum);
733,308✔
4886
    }
4887

4888
    taskNum = taosArrayGetSize(pVg->calcReaders);
1,238,462✔
4889
    if (taskNum > 0) {
1,238,462✔
4890
      msmCheckTaskListStatus(streamId, taosArrayGet(pVg->calcReaders, 0), taskNum);
796,163✔
4891
    }
4892
  }
4893
}
119,833✔
4894

4895
void msmHandleVgroupLost(SMnode *pMnode, int32_t vgId, SStmVgroupStatus* pVg) {
×
4896
  int64_t streamId = 0;
×
4897
  void* pIter = NULL;
×
4898
  SStmVgStreamStatus* pStream = NULL;
×
4899

4900
  if (!MST_PASS_ISOLATION(pVg->lastUpTs, 5)) {
×
4901
    mstDebug("vgroup %d lost and still in watch time, lastUpTs:%" PRId64 ", streamNum:%d", vgId, pVg->lastUpTs, (int32_t)taosHashGetSize(pVg->streamTasks));
×
4902
    return;
×
4903
  }
4904

4905
  
4906
  while (true) {
4907
    pIter = taosHashIterate(pVg->streamTasks, pIter);
×
4908
    if (NULL == pIter) {
×
4909
      break;
×
4910
    }
4911

4912
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
4913
    
4914
    msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_VGROUP_LOST, mStreamMgmt.hCtx.currentTs);
×
4915
  }
4916

4917
  taosHashClear(pVg->streamTasks);
×
4918
}
4919

4920

4921
void msmCheckVgroupStatus(SMnode *pMnode) {
291,565✔
4922
  void* pIter = NULL;
291,565✔
4923
  int32_t code = 0;
291,565✔
4924
  
4925
  while (true) {
1,103,952✔
4926
    pIter = taosHashIterate(mStreamMgmt.vgroupMap, pIter);
1,395,517✔
4927
    if (NULL == pIter) {
1,395,517✔
4928
      break;
291,565✔
4929
    }
4930

4931
    int32_t vgId = *(int32_t*)taosHashGetKey(pIter, NULL);
1,103,952✔
4932
    if ((vgId % MND_STREAM_ISOLATION_PERIOD_NUM) != mStreamMgmt.hCtx.slotIdx) {
1,103,952✔
4933
      continue;
982,283✔
4934
    }
4935
    
4936
    SStmVgroupStatus* pVg = (SStmVgroupStatus*)pIter;
121,669✔
4937

4938
    if (MST_PASS_ISOLATION(pVg->lastUpTs, 1)) {
121,669✔
4939
      SVgObj *pVgroup = mndAcquireVgroup(pMnode, vgId);
1,836✔
4940
      if (NULL == pVgroup) {
1,836✔
4941
        mstDebug("vgroup %d no longer exits, will remove all %d tasks in it", vgId, (int32_t)taosHashGetSize(pVg->streamTasks));
1,836✔
4942
        code = taosHashRemove(mStreamMgmt.vgroupMap, &vgId, sizeof(vgId));
1,836✔
4943
        if (code) {
1,836✔
4944
          mstWarn("remove vgroup %d from vgroupMap failed since %s", vgId, tstrerror(code));
×
4945
        }
4946
        continue;
1,836✔
4947
      }
4948
      mndReleaseVgroup(pMnode, pVgroup);
×
4949
      
4950
      mstWarn("vgroup %d lost, lastUpTs:%" PRId64 ", streamNum:%d", vgId, pVg->lastUpTs, (int32_t)taosHashGetSize(pVg->streamTasks));
×
4951
      
4952
      msmHandleVgroupLost(pMnode, vgId, pVg);
×
4953
      continue;
×
4954
    }
4955

4956
    mstDebug("vgroup %d online, try to check tasks status, currTs:%" PRId64 ", lastUpTs:%" PRId64, vgId, mStreamMgmt.hCtx.currentTs, pVg->lastUpTs);
119,833✔
4957

4958
    msmCheckVgroupStreamStatus(pVg->streamTasks);
119,833✔
4959
  }
4960
}
291,565✔
4961

UNCOV
4962
void msmHandleRunnerRedeploy(int64_t streamId, SStmSnodeStreamStatus* pStream, int32_t* deployNum, int32_t* deployId) {
×
UNCOV
4963
  *deployNum = 0;
×
4964
  
UNCOV
4965
  for (int32_t i = 0; i < MND_STREAM_RUNNER_DEPLOY_NUM; ++i) {
×
UNCOV
4966
    if (pStream->runners[i]) {
×
UNCOV
4967
      int32_t taskNum = taosArrayGetSize(pStream->runners[i]);
×
UNCOV
4968
      for (int32_t t = 0; t < taskNum; ++t) {
×
UNCOV
4969
        SStmTaskStatus* pTask = taosArrayGetP(pStream->runners[i], t);
×
UNCOV
4970
        int8_t stopped = atomic_load_8(&((SStmStatus*)pTask->pStream)->stopped);
×
UNCOV
4971
        if (stopped) {
×
UNCOV
4972
          mstsDebug("stream already stopped %d, ignore it", stopped);
×
UNCOV
4973
          *deployNum = 0;
×
UNCOV
4974
          return;
×
4975
        }
4976

UNCOV
4977
        int64_t newSid = atomic_add_fetch_64(&pTask->id.seriousId, 1);
×
UNCOV
4978
        mstsDebug("task %" PRIx64 " SID updated to %" PRIx64, pTask->id.taskId, newSid);
×
4979
      }
4980
      
UNCOV
4981
      deployId[*deployNum] = i;
×
UNCOV
4982
      (*deployNum)++;
×
4983
    }
4984
  }
4985
}
4986

4987
void msmHandleSnodeLost(SMnode *pMnode, SStmSnodeStatus* pSnode) {
855✔
4988
  pSnode->runnerThreadNum = -1;
855✔
4989

4990
  (void)msmSTAddSnodesToMap(pMnode);
855✔
4991

4992
  int64_t streamId = 0;
855✔
4993
  void* pIter = NULL;
855✔
4994
  SStmSnodeStreamStatus* pStream = NULL;
855✔
4995
  int32_t deployNum = 0;
855✔
4996
  SStmTaskAction task = {0};
855✔
4997
  
4998
  while (true) {
4999
    pIter = taosHashIterate(pSnode->streamTasks, pIter);
1,368✔
5000
    if (NULL == pIter) {
1,368✔
5001
      break;
855✔
5002
    }
5003

5004
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
513✔
5005
    
5006
    task.streamId = streamId;
513✔
5007
    
5008
    pStream = (SStmSnodeStreamStatus*)pIter;
513✔
5009
    if (pStream->trigger) {
513✔
5010
      int8_t stopped = atomic_load_8(&((SStmStatus*)pStream->trigger->pStream)->stopped);
513✔
5011
      if (stopped) {
513✔
UNCOV
5012
        mstsDebug("stream already stopped %d, ignore it", stopped);
×
UNCOV
5013
        continue;
×
5014
      }
5015

5016
      mstsInfo("snode lost with trigger task %" PRIx64 ", will try to restart current stream", pStream->trigger->id.taskId);
513✔
5017
      
5018
      msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_SNODE_LOST, mStreamMgmt.hCtx.currentTs);
513✔
5019
    } else {
UNCOV
5020
      msmHandleRunnerRedeploy(streamId, pStream, &task.deployNum, task.deployId);
×
5021
      
UNCOV
5022
      if (task.deployNum > 0) {
×
5023
        //task.triggerStatus = pStream->trigger;
UNCOV
5024
        task.multiRunner = true;
×
UNCOV
5025
        task.type = STREAM_RUNNER_TASK;
×
5026
        
UNCOV
5027
        mstPostTaskAction(mStreamMgmt.actionQ, &task, STREAM_ACT_DEPLOY);
×
5028
        
UNCOV
5029
        mstsInfo("runner tasks %d redeploys added to actionQ", task.deployNum);
×
5030
      }
5031
    }
5032
  }
5033

5034
  taosHashClear(pSnode->streamTasks);
855✔
5035
}
855✔
5036

5037

5038
void msmCheckSnodeStreamStatus(SHashObj* pStreams) {
33,654✔
5039
  void* pIter = NULL;
33,654✔
5040
  SStmSnodeStreamStatus* pSnode = NULL;
33,654✔
5041
  int64_t streamId = 0;
33,654✔
5042
  
5043
  while (true) {
5044
    pIter = taosHashIterate(pStreams, pIter);
423,501✔
5045
    if (NULL == pIter) {
423,501✔
5046
      break;
33,654✔
5047
    }
5048

5049
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
389,847✔
5050
    pSnode = (SStmSnodeStreamStatus*)pIter;
389,847✔
5051

5052
    if (NULL != pSnode->trigger) {
389,847✔
5053
      msmCheckTaskListStatus(streamId, &pSnode->trigger, 1);
379,326✔
5054
    }
5055

5056
    for (int32_t i = 0; i < MND_STREAM_RUNNER_DEPLOY_NUM; ++i) {
1,559,388✔
5057
      int32_t taskNum = taosArrayGetSize(pSnode->runners[i]);
1,169,541✔
5058
      if (taskNum > 0) {
1,169,541✔
5059
        msmCheckTaskListStatus(streamId, taosArrayGet(pSnode->runners[i], 0), taskNum);
1,104,156✔
5060
      }
5061
    }
5062
  }
5063
}
33,654✔
5064

5065

5066
void msmCheckSnodeStatus(SMnode *pMnode) {
291,565✔
5067
  void* pIter = NULL;
291,565✔
5068
  
5069
  while (true) {
349,405✔
5070
    pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter);
640,970✔
5071
    if (NULL == pIter) {
640,970✔
5072
      break;
291,565✔
5073
    }
5074

5075
    int32_t snodeId = *(int32_t*)taosHashGetKey(pIter, NULL);
349,405✔
5076
    if ((snodeId % MND_STREAM_ISOLATION_PERIOD_NUM) != mStreamMgmt.hCtx.slotIdx) {
349,405✔
5077
      continue;
307,129✔
5078
    }
5079

5080
    mstDebug("start to check snode %d status, currTs:%" PRId64, snodeId, mStreamMgmt.hCtx.currentTs);
42,276✔
5081
    
5082
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
42,276✔
5083
    if (NULL == pSnode->streamTasks) {
42,276✔
5084
      mstDebug("ignore snode %d health check since empty tasks", snodeId);
7,938✔
5085
      continue;
7,938✔
5086
    }
5087
    
5088
    if (MST_PASS_ISOLATION(pSnode->lastUpTs, 1)) {
34,338✔
5089
      mstInfo("snode %d lost, lastUpTs:%" PRId64 ", runnerThreadNum:%d, streamNum:%d", 
684✔
5090
          snodeId, pSnode->lastUpTs, pSnode->runnerThreadNum, (int32_t)taosHashGetSize(pSnode->streamTasks));
5091
      
5092
      msmHandleSnodeLost(pMnode, pSnode);
684✔
5093
      continue;
684✔
5094
    }
5095
    
5096
    mstDebug("snode %d online, try to check tasks status, currTs:%" PRId64 ", lastUpTs:%" PRId64, snodeId, mStreamMgmt.hCtx.currentTs, pSnode->lastUpTs);
33,654✔
5097

5098
    msmCheckSnodeStreamStatus(pSnode->streamTasks);
33,654✔
5099
  }
5100
}
291,565✔
5101

5102

5103
void msmCheckTasksStatus(SMnode *pMnode) {
291,565✔
5104
  mstDebug("start to check tasks status, currTs:%" PRId64, mStreamMgmt.hCtx.currentTs);
291,565✔
5105

5106
  msmCheckVgroupStatus(pMnode);
291,565✔
5107
  msmCheckSnodeStatus(pMnode);
291,565✔
5108
}
291,565✔
5109

5110
void msmCheckSnodesState(SMnode *pMnode) {
291,565✔
5111
  if (!MST_READY_FOR_SNODE_LOOP()) {
291,565✔
5112
    return;
259,851✔
5113
  }
5114

5115
  mstDebug("ready to check snode loop, lastTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_SNODE].ts);
31,714✔
5116

5117
  void* pIter = NULL;
31,714✔
5118
  int32_t snodeId = 0;
31,714✔
5119
  while (true) {
34,483✔
5120
    pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter);
66,197✔
5121
    if (NULL == pIter) {
66,197✔
5122
      break;
31,714✔
5123
    }
5124

5125
    snodeId = *(int32_t*)taosHashGetKey(pIter, NULL);
34,483✔
5126
    if (sdbCheckExists(pMnode->pSdb, SDB_SNODE, &snodeId)) {
34,483✔
5127
      continue;
34,312✔
5128
    }
5129

5130
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
171✔
5131
    if (NULL == pSnode->streamTasks) {
171✔
5132
      mstDebug("snode %d already cleanup, try to rm it", snodeId);
×
5133
      TAOS_UNUSED(taosHashRemove(mStreamMgmt.snodeMap, &snodeId, sizeof(snodeId)));
×
5134
      continue;
×
5135
    }
5136
    
5137
    mstWarn("snode %d lost while streams remain, will redeploy all and rm it, lastUpTs:%" PRId64 ", runnerThreadNum:%d, streamNum:%d", 
171✔
5138
        snodeId, pSnode->lastUpTs, pSnode->runnerThreadNum, (int32_t)taosHashGetSize(pSnode->streamTasks));
5139
    
5140
    msmHandleSnodeLost(pMnode, pSnode);
171✔
5141
  }
5142

5143
  MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_MAP, mStreamMgmt.hCtx.currentTs);
31,714✔
5144
}
5145

5146
bool msmCheckNeedHealthCheck(SMnode *pMnode) {
11,374,108✔
5147
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
11,374,108✔
5148
  if (0 == active || MND_STM_STATE_NORMAL != state) {
11,374,108✔
5149
    mstTrace("ignore health check since active:%d state:%d", active, state);
2,363✔
5150
    return false;
2,363✔
5151
  }
5152

5153
  if (sdbGetSize(pMnode->pSdb, SDB_STREAM) <= 0) {
11,371,745✔
5154
    mstTrace("ignore health check since no stream now");
10,788,615✔
5155
    return false;
10,788,615✔
5156
  }
5157

5158
  return true;
583,130✔
5159
}
5160

5161
void msmHealthCheck(SMnode *pMnode) {
11,082,543✔
5162
  if (!msmCheckNeedHealthCheck(pMnode)) {
11,082,543✔
5163
    return;
10,790,978✔
5164
  }
5165

5166
  mstDebug("start wait health check, currentTs:%" PRId64,  taosGetTimestampMs());
554,511✔
5167
  
5168
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, false);
291,565✔
5169
  if (!msmCheckNeedHealthCheck(pMnode)) {
291,565✔
5170
    taosWUnLockLatch(&mStreamMgmt.runtimeLock);
×
5171
    return;
×
5172
  }
5173
  
5174
  mStreamMgmt.hCtx.slotIdx = (mStreamMgmt.hCtx.slotIdx + 1) % MND_STREAM_ISOLATION_PERIOD_NUM;
291,565✔
5175
  mStreamMgmt.hCtx.currentTs = taosGetTimestampMs();
291,565✔
5176

5177
  mstDebug("start health check, soltIdx:%d, checkStartTs:%" PRId64, mStreamMgmt.hCtx.slotIdx, mStreamMgmt.hCtx.currentTs);
291,565✔
5178
  
5179
  msmCheckStreamsStatus(pMnode);
291,565✔
5180
  msmCheckTasksStatus(pMnode);
291,565✔
5181
  msmCheckSnodesState(pMnode);
291,565✔
5182

5183
  taosWUnLockLatch(&mStreamMgmt.runtimeLock);
291,565✔
5184

5185
  mstDebug("end health check, soltIdx:%d, checkStartTs:%" PRId64, mStreamMgmt.hCtx.slotIdx, mStreamMgmt.hCtx.currentTs);
291,565✔
5186
}
5187

5188
static bool msmUpdateProfileStreams(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
825✔
5189
  SStreamObj *pStream = pObj;
825✔
5190
  if (atomic_load_8(&pStream->userDropped) || atomic_load_8(&pStream->userStopped)) {
825✔
5191
    return true;
×
5192
  }
5193
  
5194
  pStream->updateTime = *(int64_t*)p1;
825✔
5195
  
5196
  (*(int32_t*)p2)++;
825✔
5197
  
5198
  return true;
825✔
5199
}
5200

5201
int32_t msmGetTriggerTaskAddr(SMnode *pMnode, int64_t streamId, SStreamTaskAddr* pAddr) {
×
5202
  int32_t code = 0;
×
5203
  int8_t  stopped = 0;
×
5204
  
5205
  (void)mstWaitLock(&mStreamMgmt.runtimeLock, true);
×
5206
  
5207
  SStmStatus* pStatus = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
5208
  if (NULL == pStatus) {
×
5209
    mstsError("stream not exists in streamMap, streamRemains:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
5210
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
5211
    goto _exit;
×
5212
  }
5213

5214
  stopped = atomic_load_8(&pStatus->stopped);
×
5215
  if (stopped) {
×
5216
    mstsError("stream already stopped, stopped:%d", stopped);
×
5217
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
5218
    goto _exit;
×
5219
  }
5220

5221
  if (pStatus->triggerTask && STREAM_STATUS_RUNNING == pStatus->triggerTask->status) {
×
5222
    pAddr->taskId = pStatus->triggerTask->id.taskId;
×
5223
    pAddr->nodeId = pStatus->triggerTask->id.nodeId;
×
5224
    pAddr->epset = mndGetDnodeEpsetById(pMnode, pAddr->nodeId);
×
5225
    mstsDebug("stream trigger task %" PRIx64 " got with nodeId %d", pAddr->taskId, pAddr->nodeId);
×
5226
    goto _exit;
×
5227
  }
5228

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

5232
_exit:
×
5233
  
5234
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
×
5235

5236
  return code;
×
5237
}
5238

5239
int32_t msmInitRuntimeInfo(SMnode *pMnode) {
368,571✔
5240
  int32_t code = TSDB_CODE_SUCCESS;
368,571✔
5241
  int32_t lino = 0;
368,571✔
5242
  int32_t vnodeNum = sdbGetSize(pMnode->pSdb, SDB_VGROUP);
368,571✔
5243
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
368,571✔
5244
  int32_t dnodeNum = sdbGetSize(pMnode->pSdb, SDB_DNODE);
368,571✔
5245

5246
  MND_STREAM_SET_LAST_TS(STM_EVENT_ACTIVE_BEGIN, taosGetTimestampMs());
737,088✔
5247

5248
  mStreamMgmt.stat.activeTimes++;
368,571✔
5249
  mStreamMgmt.threadNum = tsNumOfMnodeStreamMgmtThreads;
368,571✔
5250
  mStreamMgmt.tCtx = taosMemoryCalloc(mStreamMgmt.threadNum, sizeof(SStmThreadCtx));
368,571✔
5251
  if (NULL == mStreamMgmt.tCtx) {
368,571✔
5252
    code = terrno;
×
5253
    mstError("failed to initialize the stream runtime tCtx, threadNum:%d, error:%s", mStreamMgmt.threadNum, tstrerror(code));
×
5254
    goto _exit;
×
5255
  }
5256

5257
  mStreamMgmt.actionQ = taosMemoryCalloc(1, sizeof(SStmActionQ));
368,571✔
5258
  if (mStreamMgmt.actionQ == NULL) {
368,571✔
5259
    code = terrno;
×
5260
    mError("failed to initialize the stream runtime actionQ, error:%s", tstrerror(code));
×
5261
    goto _exit;
×
5262
  }
5263
  
5264
  mStreamMgmt.actionQ->head = taosMemoryCalloc(1, sizeof(SStmQNode));
368,571✔
5265
  TSDB_CHECK_NULL(mStreamMgmt.actionQ->head, code, lino, _exit, terrno);
368,571✔
5266
  
5267
  mStreamMgmt.actionQ->tail = mStreamMgmt.actionQ->head;
368,571✔
5268
  
5269
  for (int32_t i = 0; i < mStreamMgmt.threadNum; ++i) {
2,211,236✔
5270
    SStmThreadCtx* pCtx = mStreamMgmt.tCtx + i;
1,842,665✔
5271

5272
    for (int32_t m = 0; m < STREAM_MAX_GROUP_NUM; ++m) {
11,055,990✔
5273
      pCtx->deployStm[m] = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
9,213,325✔
5274
      if (pCtx->deployStm[m] == NULL) {
9,213,325✔
5275
        code = terrno;
×
5276
        mError("failed to initialize the stream runtime deployStm[%d][%d], error:%s", i, m, tstrerror(code));
×
5277
        goto _exit;
×
5278
      }
5279
      taosHashSetFreeFp(pCtx->deployStm[m], tDeepFreeSStmStreamDeploy);
9,213,325✔
5280
      
5281
      pCtx->actionStm[m] = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
9,213,325✔
5282
      if (pCtx->actionStm[m] == NULL) {
9,213,325✔
5283
        code = terrno;
×
5284
        mError("failed to initialize the stream runtime actionStm[%d][%d], error:%s", i, m, tstrerror(code));
×
5285
        goto _exit;
×
5286
      }
5287
      taosHashSetFreeFp(pCtx->actionStm[m], mstDestroySStmAction);
9,213,325✔
5288
    }
5289
  }
5290
  
5291
  mStreamMgmt.streamMap = taosHashInit(MND_STREAM_DEFAULT_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
368,571✔
5292
  if (mStreamMgmt.streamMap == NULL) {
368,571✔
5293
    code = terrno;
×
5294
    mError("failed to initialize the stream runtime streamMap, error:%s", tstrerror(code));
×
5295
    goto _exit;
×
5296
  }
5297
  taosHashSetFreeFp(mStreamMgmt.streamMap, mstDestroySStmStatus);
368,571✔
5298
  
5299
  mStreamMgmt.taskMap = taosHashInit(MND_STREAM_DEFAULT_TASK_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
368,571✔
5300
  if (mStreamMgmt.taskMap == NULL) {
368,571✔
5301
    code = terrno;
×
5302
    mError("failed to initialize the stream runtime taskMap, error:%s", tstrerror(code));
×
5303
    goto _exit;
×
5304
  }
5305
  
5306
  mStreamMgmt.vgroupMap = taosHashInit(vnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
368,571✔
5307
  if (mStreamMgmt.vgroupMap == NULL) {
368,571✔
5308
    code = terrno;
×
5309
    mError("failed to initialize the stream runtime vgroupMap, error:%s", tstrerror(code));
×
5310
    goto _exit;
×
5311
  }
5312
  taosHashSetFreeFp(mStreamMgmt.vgroupMap, mstDestroySStmVgroupStatus);
368,571✔
5313

5314
  mStreamMgmt.snodeMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
368,571✔
5315
  if (mStreamMgmt.snodeMap == NULL) {
368,571✔
5316
    code = terrno;
×
5317
    mError("failed to initialize the stream runtime snodeMap, error:%s", tstrerror(code));
×
5318
    goto _exit;
×
5319
  }
5320
  taosHashSetFreeFp(mStreamMgmt.snodeMap, mstDestroySStmSnodeStatus);
368,571✔
5321
  
5322
  mStreamMgmt.dnodeMap = taosHashInit(dnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
368,571✔
5323
  if (mStreamMgmt.dnodeMap == NULL) {
368,571✔
5324
    code = terrno;
×
5325
    mError("failed to initialize the stream runtime dnodeMap, error:%s", tstrerror(code));
×
5326
    goto _exit;
×
5327
  }
5328

5329
  mStreamMgmt.toDeployVgMap = taosHashInit(vnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
368,571✔
5330
  if (mStreamMgmt.toDeployVgMap == NULL) {
368,571✔
5331
    code = terrno;
×
5332
    mError("failed to initialize the stream runtime toDeployVgMap, error:%s", tstrerror(code));
×
5333
    goto _exit;
×
5334
  }
5335
  taosHashSetFreeFp(mStreamMgmt.toDeployVgMap, mstDestroySStmVgTasksToDeploy);
368,571✔
5336
  
5337
  mStreamMgmt.toDeploySnodeMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
368,571✔
5338
  if (mStreamMgmt.toDeploySnodeMap == NULL) {
368,571✔
5339
    code = terrno;
×
5340
    mError("failed to initialize the stream runtime toDeploySnodeMap, error:%s", tstrerror(code));
×
5341
    goto _exit;
×
5342
  }
5343
  taosHashSetFreeFp(mStreamMgmt.toDeploySnodeMap, mstDestroySStmSnodeTasksDeploy);
368,571✔
5344

5345
  mStreamMgmt.toUpdateScanMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
368,571✔
5346
  if (mStreamMgmt.toUpdateScanMap == NULL) {
368,571✔
5347
    code = terrno;
×
5348
    mError("failed to initialize the stream runtime toUpdateScanMap, error:%s", tstrerror(code));
×
5349
    goto _exit;
×
5350
  }
5351
  taosHashSetFreeFp(mStreamMgmt.toUpdateScanMap, mstDestroyScanAddrList);
368,571✔
5352

5353
  TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pMnode));
368,571✔
5354
  TAOS_CHECK_EXIT(msmSTAddDnodesToMap(pMnode));
368,571✔
5355

5356
  mStreamMgmt.lastTaskId = 1;
368,571✔
5357

5358
  int32_t activeStreamNum = 0;
368,571✔
5359
  sdbTraverse(pMnode->pSdb, SDB_STREAM, msmUpdateProfileStreams, &MND_STREAM_GET_LAST_TS(STM_EVENT_ACTIVE_BEGIN), &activeStreamNum, NULL);
368,571✔
5360

5361
  if (activeStreamNum > 0) {
368,571✔
5362
    msmSetInitRuntimeState(MND_STM_STATE_WATCH);
663✔
5363
  } else {
5364
    msmSetInitRuntimeState(MND_STM_STATE_NORMAL);
367,908✔
5365
  }
5366

5367
_exit:
368,571✔
5368

5369
  if (code) {
368,571✔
5370
    msmDestroyRuntimeInfo(pMnode);
×
5371
    mstError("%s failed at line %d since %s", __FUNCTION__, lino, tstrerror(code));
×
5372
  } else {
5373
    mstInfo("mnode stream runtime init done");
368,571✔
5374
  }
5375

5376
  return code;
368,571✔
5377
}
5378

5379

5380

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