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

taosdata / TDengine / #4609

28 Jul 2025 03:45AM UTC coverage: 60.413% (-0.7%) from 61.072%
#4609

push

travis-ci

web-flow
merge: from 3.3.6 to main branch #32314 

Merge/3.3.6tomain

138583 of 291345 branches covered (47.57%)

Branch coverage included in aggregate %.

79 of 97 new or added lines in 12 files covered. (81.44%)

9880 existing lines in 148 files now uncovered.

208900 of 283831 relevant lines covered (73.6%)

18073489.5 hits per line

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

60.04
/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

32
void msmDestroyActionQ() {
5,083✔
33
  SStmQNode* pQNode = NULL;
5,083✔
34

35
  if (NULL == mStreamMgmt.actionQ) {
5,083✔
36
    return;
2,676✔
37
  }
38

39
  while (mndStreamActionDequeue(mStreamMgmt.actionQ, &pQNode)) {
2,411✔
40
  }
41

42
  taosMemoryFreeClear(mStreamMgmt.actionQ->head);
2,407!
43
  taosMemoryFreeClear(mStreamMgmt.actionQ);
2,407!
44
}
45

46
void msmDestroySStmThreadCtx(SStmThreadCtx* pCtx) {
12,011✔
47
  for (int32_t m = 0; m < STREAM_MAX_GROUP_NUM; ++m) {
72,066✔
48
    taosHashCleanup(pCtx->deployStm[m]);
60,055✔
49
    taosHashCleanup(pCtx->actionStm[m]);
60,055✔
50
  }
51
}
12,011✔
52

53
void msmDestroyThreadCtxs() {
5,083✔
54
  if (NULL == mStreamMgmt.tCtx) {
5,083✔
55
    return;
2,676✔
56
  }
57
  
58
  for (int32_t i = 0; i < mStreamMgmt.threadNum; ++i) {
14,418✔
59
    msmDestroySStmThreadCtx(mStreamMgmt.tCtx + i);
12,011✔
60
  }
61
  taosMemoryFreeClear(mStreamMgmt.tCtx);
2,407!
62
}
63

64

65
void msmDestroyRuntimeInfo(SMnode *pMnode) {
5,083✔
66
  msmDestroyActionQ();
5,083✔
67
  msmDestroyThreadCtxs();
5,083✔
68

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

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

90
  memset(mStreamMgmt.lastTs, 0, sizeof(mStreamMgmt.lastTs));
5,083✔
91

92
  mstInfo("mnode stream mgmt destroyed");  
5,083!
93
}
5,083✔
94

95

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

101
  mstsInfo("try to stop stream for error: %s", tstrerror(errCode));
20!
102

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

110
    pStatus = pStream;
20✔
111
  }
112

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

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

124
  pStatus->fatalRetryTimes++;
20✔
125
  pStatus->fatalError = errCode;
20✔
126
  pStatus->fatalRetryDuration = (pStatus->fatalRetryTimes > 10) ? MST_MAX_RETRY_DURATION : MST_ISOLATION_DURATION;
20!
127
  pStatus->fatalRetryTs = currTs + pStatus->fatalRetryDuration;
20✔
128

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

135
_exit:
8✔
136

137
  taosHashRelease(mStreamMgmt.streamMap, pStream);
20✔
138

139
  if (code) {
20!
UNCOV
140
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
141
  }
142

143
  return code;
20✔
144
}
145

146

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

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

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

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

196
    code = TSDB_CODE_SUCCESS;
178✔
197
  
198
    sdbRelease(pMnode->pSdb, pSnode);
178✔
199
  }
200

201
  pSnode = NULL;
2,485✔
202

203
_exit:
2,485✔
204

205
  if (code) {
2,485!
UNCOV
206
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
207
  }
208

209
  return code;
2,485✔
210
}
211

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

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

232
    code = TSDB_CODE_SUCCESS;
4,756✔
233
    sdbRelease(pMnode->pSdb, pDnode);
4,756✔
234
  }
235

236
  pDnode = NULL;
4,730✔
237

238
_exit:
4,730✔
239

240
  if (code) {
4,730!
UNCOV
241
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
242
  }
243

244
  return code;
4,730✔
245
}
246

247

248

249
static int32_t msmSTAddToTaskMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SStmTaskStatus* pTask) {
1,666✔
250
  int32_t code = TSDB_CODE_SUCCESS;
1,666✔
251
  int32_t lino = 0;
1,666✔
252
  int32_t taskNum = pTask ? 1 : taosArrayGetSize(pTasks);
1,666✔
253
  int64_t key[2] = {streamId, 0};
1,666✔
254
  
255
  for (int32_t i = 0; i < taskNum; ++i) {
3,221✔
256
    SStmTaskStatus* pStatus = pTask ? pTask : taosArrayGet(pTasks, i);
1,555✔
257
    key[1] = pStatus->id.taskId;
1,555✔
258
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.taskMap, key, sizeof(key), &pStatus, POINTER_BYTES));
1,555!
259
    mstsDebug("task %" PRIx64" tidx %d added to taskMap", pStatus->id.taskId, pStatus->id.taskIdx);
1,555✔
260
  }
261
  
262
_exit:
1,666✔
263

264
  if (code) {
1,666!
UNCOV
265
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
266
  }
267
  
268
  return code;
1,666✔
269
}
270

271
static int32_t msmSTAddToVgStreamHash(SHashObj* pHash, int64_t streamId, SStmTaskStatus* pStatus, bool trigReader) {
470✔
272
  int32_t code = TSDB_CODE_SUCCESS;
470✔
273
  int32_t lino = 0;
470✔
274
  SStmVgStreamStatus* pStream = taosHashGet(pHash, &streamId, sizeof(streamId));
470✔
275
  if (NULL == pStream) {
470✔
276
    SStmVgStreamStatus stream = {0};
370✔
277
    if (trigReader) {
370✔
278
      stream.trigReaders = taosArrayInit(1, POINTER_BYTES);
298✔
279
      TSDB_CHECK_NULL(stream.trigReaders, code, lino, _exit, terrno);
298!
280
      TSDB_CHECK_NULL(taosArrayPush(stream.trigReaders, &pStatus), code, lino, _exit, terrno);
596!
281
    } else {
282
      stream.calcReaders = taosArrayInit(2, POINTER_BYTES);
72✔
283
      TSDB_CHECK_NULL(stream.calcReaders, code, lino, _exit, terrno);
72!
284
      TSDB_CHECK_NULL(taosArrayPush(stream.calcReaders, &pStatus), code, lino, _exit, terrno);
144!
285
    }
286
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &stream, sizeof(stream)));
370!
287
    goto _exit;
370✔
288
  }
289
  
290
  if (trigReader) {
100✔
291
    if (NULL == pStream->trigReaders) {
21!
292
      pStream->trigReaders = taosArrayInit(1, POINTER_BYTES);
21✔
293
      TSDB_CHECK_NULL(pStream->trigReaders, code, lino, _exit, terrno);
21!
294
    }
295
    
296
    TSDB_CHECK_NULL(taosArrayPush(pStream->trigReaders, &pStatus), code, lino, _exit, terrno);
42!
297
    goto _exit;
21✔
298
  }
299
  
300
  if (NULL == pStream->calcReaders) {
79✔
301
    pStream->calcReaders = taosArrayInit(1, POINTER_BYTES);
75✔
302
    TSDB_CHECK_NULL(pStream->calcReaders, code, lino, _exit, terrno);
75!
303
  }
304

305
  TSDB_CHECK_NULL(taosArrayPush(pStream->calcReaders, &pStatus), code, lino, _exit, terrno);
158!
306

307
_exit:
79✔
308

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

317
  return code;
470✔
318
}
319

320
static int32_t msmSTAddToVgroupMapImpl(int64_t streamId, SStmTaskStatus* pStatus, bool trigReader) {
470✔
321
  int32_t code = TSDB_CODE_SUCCESS;
470✔
322
  int32_t lino = 0;
470✔
323
  SStmVgroupStatus vg = {0};
470✔
324

325
  SStmVgroupStatus* pVg = taosHashGet(mStreamMgmt.vgroupMap, &pStatus->id.nodeId, sizeof(pStatus->id.nodeId));
470✔
326
  if (NULL == pVg) {
470✔
327
    vg.streamTasks = taosHashInit(2, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
104✔
328
    TSDB_CHECK_NULL(vg.streamTasks, code, lino, _exit, terrno);
104!
329
    taosHashSetFreeFp(vg.streamTasks, mstDestroySStmVgStreamStatus);
104✔
330

331
    vg.lastUpTs = taosGetTimestampMs();
104✔
332
    TAOS_CHECK_EXIT(msmSTAddToVgStreamHash(vg.streamTasks, streamId, pStatus, trigReader));
104!
333
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.vgroupMap, &pStatus->id.nodeId, sizeof(pStatus->id.nodeId), &vg, sizeof(vg)));
104!
334
  } else {
335
    TAOS_CHECK_EXIT(msmSTAddToVgStreamHash(pVg->streamTasks, streamId, pStatus, trigReader));
366!
336
  }
337
  
338
_exit:
366✔
339

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

347
  return code;
470✔
348
}
349

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

UNCOV
358
  while (true) {
×
359
    SStmVgTasksToDeploy* pVg = taosHashAcquire(pVgMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId));
498✔
360
    if (NULL == pVg) {
498✔
361
      vg.taskList = taosArrayInit(20, sizeof(SStmTaskToDeployExt));
152✔
362
      TSDB_CHECK_NULL(vg.taskList, code, lino, _return, terrno);
152!
363
      TSDB_CHECK_NULL(taosArrayPush(vg.taskList, &ext), code, lino, _return, terrno);
304!
364
      code = taosHashPut(pVgMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &vg, sizeof(SStmVgTasksToDeploy));
152✔
365
      if (TSDB_CODE_SUCCESS == code) {
152!
366
        goto _return;
152✔
367
      }
368

369
      if (TSDB_CODE_DUP_KEY != code) {
×
370
        goto _return;
×
371
      }    
372

373
      taosArrayDestroy(vg.taskList);
×
374
      continue;
×
375
    }
376

377
    taosWLockLatch(&pVg->lock);
346✔
378
    if (NULL == pVg->taskList) {
346!
UNCOV
379
      pVg->taskList = taosArrayInit(20, sizeof(SStmTaskToDeployExt));
×
UNCOV
380
      TSDB_CHECK_NULL(pVg->taskList, code, lino, _return, terrno);
×
381
    }
382
    if (NULL == taosArrayPush(pVg->taskList, &ext)) {
692!
UNCOV
383
      taosWUnLockLatch(&pVg->lock);
×
UNCOV
384
      TSDB_CHECK_NULL(NULL, code, lino, _return, terrno);
×
385
    }
386
    taosWUnLockLatch(&pVg->lock);
346✔
387
    
388
    taosHashRelease(pVgMap, pVg);
346✔
389
    break;
346✔
390
  }
391
  
392
_return:
498✔
393

394
  if (code) {
498!
UNCOV
395
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
396
  } else {
397
    int32_t num = atomic_add_fetch_32(&mStreamMgmt.toDeployVgTaskNum, 1);
498✔
398
    msttDebug("task added to toDeployVgTaskNum, vgToDeployTaskNum:%d", num);
498✔
399
  }
400

401
  return code;
498✔
402
}
403

404

405
static int32_t msmSTAddToSnodeStreamHash(SHashObj* pHash, int64_t streamId, SStmTaskStatus* pStatus, int32_t deployId) {
1,095✔
406
  int32_t code = TSDB_CODE_SUCCESS;
1,095✔
407
  int32_t lino = 0;
1,095✔
408
  SStmSnodeStreamStatus* pStream = taosHashGet(pHash, &streamId, sizeof(streamId));
1,095✔
409
  if (NULL == pStream) {
1,095✔
410
    SStmSnodeStreamStatus stream = {0};
303✔
411
    if (deployId < 0) {
303✔
412
      stream.trigger = pStatus;
1✔
413
    } else {
414
      stream.runners[deployId] = taosArrayInit(2, POINTER_BYTES);
302✔
415
      TSDB_CHECK_NULL(stream.runners[deployId], code, lino, _exit, terrno);
302!
416
      TSDB_CHECK_NULL(taosArrayPush(stream.runners[deployId], &pStatus), code, lino, _exit, terrno);
604!
417
    }
418
    
419
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &stream, sizeof(stream)));
303!
420
    goto _exit;
303✔
421
  }
422
  
423
  if (deployId < 0) {
792✔
424
    if (NULL != pStream->trigger) {
271!
UNCOV
425
      mstsWarn("stream already got trigger task %" PRIx64 " SID:%" PRIx64 " in snode %d, replace it with task %" PRIx64 " SID:%" PRIx64, 
×
426
          pStream->trigger->id.taskId, pStream->trigger->id.seriousId, pStatus->id.nodeId, pStatus->id.taskId, pStatus->id.seriousId);
427
    }
428
    
429
    pStream->trigger = pStatus;
271✔
430
    goto _exit;
271✔
431
  }
432
  
433
  if (NULL == pStream->runners[deployId]) {
521!
434
    pStream->runners[deployId] = taosArrayInit(2, POINTER_BYTES);
521✔
435
    TSDB_CHECK_NULL(pStream->runners[deployId], code, lino, _exit, terrno);
521!
436
  }
437

438
  TSDB_CHECK_NULL(taosArrayPush(pStream->runners[deployId], &pStatus), code, lino, _exit, terrno);
1,042!
439

440
_exit:
521✔
441

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

450
  return code;
1,095✔
451
}
452

453

454
static int32_t msmSTAddToSnodeMapImpl(int64_t streamId, SStmTaskStatus* pStatus, int32_t deployId) {
1,095✔
455
  int32_t code = TSDB_CODE_SUCCESS;
1,095✔
456
  int32_t lino = 0;
1,095✔
457

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

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

481
  return code;
1,095✔
482
}
483

484

485

486
static int32_t msmTDAddTriggerToSnodeMap(SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
272✔
487
  int32_t code = TSDB_CODE_SUCCESS;
272✔
488
  int32_t lino = 0;
272✔
489
  int64_t streamId = pStream->pCreate->streamId;
272✔
490
  SStmSnodeTasksDeploy snode = {0};
272✔
491
  SStmTaskToDeployExt ext;
492
  SStreamTask* pTask = &pDeploy->task;
272✔
493

494
  while (true) {
×
495
    SStmSnodeTasksDeploy* pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId));
272✔
496
    if (NULL == pSnode) {
272✔
497
      snode.triggerList = taosArrayInit(10, sizeof(SStmTaskToDeployExt));
1✔
498
      TSDB_CHECK_NULL(snode.triggerList, code, lino, _return, terrno);
1!
499

500
      ext.deploy = *pDeploy;
1✔
501
      ext.deployed = false;
1✔
502
      TSDB_CHECK_NULL(taosArrayPush(snode.triggerList, &ext), code, lino, _return, terrno);
2!
503

504
      code = taosHashPut(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &snode, sizeof(snode));
1✔
505
      if (TSDB_CODE_SUCCESS == code) {
1!
506
        goto _return;
1✔
507
      }
508

UNCOV
509
      if (TSDB_CODE_DUP_KEY != code) {
×
UNCOV
510
        goto _return;
×
511
      }    
512

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

541
  if (code) {
272!
UNCOV
542
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
543
  } else {
544
    msttDebug("trigger task added to toDeploySnodeMap, tidx:%d", pTask->taskIdx);
272✔
545
  }
546

547
  return code;
272✔
548
}
549

550
static int32_t msmTDAddRunnerToSnodeMap(SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
823✔
551
  int32_t code = TSDB_CODE_SUCCESS;
823✔
552
  int32_t lino = 0;
823✔
553
  int64_t streamId = pStream->pCreate->streamId;
823✔
554
  SStmSnodeTasksDeploy snode = {0};
823✔
555
  SStmTaskToDeployExt ext;
556
  SStreamTask* pTask = &pDeploy->task;
823✔
557

UNCOV
558
  while (true) {
×
559
    SStmSnodeTasksDeploy* pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId));
823✔
560
    if (NULL == pSnode) {
823✔
561
      snode.runnerList = taosArrayInit(10, sizeof(SStmTaskToDeployExt));
80✔
562
      TSDB_CHECK_NULL(snode.runnerList, code, lino, _return, terrno);
80!
563

564
      ext.deploy = *pDeploy;
80✔
565
      ext.deployed = false;
80✔
566
      TSDB_CHECK_NULL(taosArrayPush(snode.runnerList, &ext), code, lino, _return, terrno);
160!
567

568
      code = taosHashPut(mStreamMgmt.toDeploySnodeMap, &pDeploy->task.nodeId, sizeof(pDeploy->task.nodeId), &snode, sizeof(snode));
80✔
569
      if (TSDB_CODE_SUCCESS == code) {
80!
570
        goto _return;
80✔
571
      }
572

573
      if (TSDB_CODE_DUP_KEY != code) {
×
574
        goto _return;
×
575
      }    
576

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

605
  if (code) {
823!
UNCOV
606
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
607
  } else {
608
    msttDebug("task added to toDeploySnodeMap, tidx:%d", pTask->taskIdx);
823✔
609
  }
610

611
  return code;
823✔
612
}
613

614
static int32_t msmTDAddRunnersToSnodeMap(SArray* runnerList, SStreamObj* pStream) {
823✔
615
  int32_t code = TSDB_CODE_SUCCESS;
823✔
616
  int32_t lino = 0;
823✔
617
  int32_t runnerNum = taosArrayGetSize(runnerList);
823✔
618
  SStmTaskDeploy* pDeploy = NULL;
823✔
619
  int64_t streamId = pStream->pCreate->streamId;
823✔
620

621
  for (int32_t i = 0; i < runnerNum; ++i) {
1,646✔
622
    pDeploy = taosArrayGet(runnerList, i);
823✔
623
    
624
    TAOS_CHECK_EXIT(msmTDAddRunnerToSnodeMap(pDeploy, pStream));
823!
625
    
626
    atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);    
823✔
627
  }
628

629
_exit:
823✔
630

631
  if (code) {
823!
UNCOV
632
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
633
  }
634

635
  return code;
823✔
636
}
637

638

639
int32_t msmUpdateSnodeUpTs(SStmGrpCtx* pCtx) {
6,664✔
640
  int32_t  code = TSDB_CODE_SUCCESS;
6,664✔
641
  int32_t  lino = 0;
6,664✔
642
  SStmSnodeStatus* pStatus = NULL;
6,664✔
643
  bool     noExists = false;
6,664✔
644

645
  while (true) {
646
    pStatus = taosHashGet(mStreamMgmt.snodeMap, &pCtx->pReq->snodeId, sizeof(pCtx->pReq->snodeId));
6,692✔
647
    if (NULL == pStatus) {
6,692✔
648
      if (noExists) {
28!
UNCOV
649
        mstWarn("snode %d not exists in snodeMap, may be dropped, ignore it", pCtx->pReq->snodeId);
×
UNCOV
650
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NODE_NOT_EXISTS);
×
651
      }
652

653
      noExists = true;
28✔
654
      TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pCtx->pMnode));
28!
655
      
656
      continue;
28✔
657
    }
658

659
    atomic_store_32(&pStatus->runnerThreadNum, pCtx->pReq->runnerThreadNum);
6,664✔
660
    
UNCOV
661
    while (true) {
×
662
      int64_t lastTsValue = atomic_load_64(&pStatus->lastUpTs);
6,664✔
663
      if (pCtx->currTs > lastTsValue) {
6,664✔
664
        if (lastTsValue == atomic_val_compare_exchange_64(&pStatus->lastUpTs, lastTsValue, pCtx->currTs)) {
6,636!
665
          mstDebug("snode %d lastUpTs updated", pCtx->pReq->snodeId);
6,636✔
666
          return code;
6,636✔
667
        }
668

UNCOV
669
        continue;
×
670
      }
671

672
      return code;
28✔
673
    }
674

675
    break;
676
  }
677

UNCOV
678
_exit:
×
679

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

UNCOV
684
  return code;  
×
685
}
686

687
void msmUpdateVgroupUpTs(SStmGrpCtx* pCtx, int32_t vgId) {
224,649✔
688
  int32_t  code = TSDB_CODE_SUCCESS;
224,649✔
689
  int32_t  lino = 0;
224,649✔
690
  SStmVgroupStatus* pStatus = taosHashGet(mStreamMgmt.vgroupMap, &vgId, sizeof(vgId));
224,649✔
691
  if (NULL == pStatus) {
224,649✔
692
    mstDebug("vgroup %d not exists in vgroupMap, ignore update upTs", vgId);
218,534✔
693
    return;
218,534✔
694
  }
695

UNCOV
696
  while (true) {
×
697
    int64_t lastTsValue = atomic_load_64(&pStatus->lastUpTs);
6,115✔
698
    if (pCtx->currTs > lastTsValue) {
6,115✔
699
      if (lastTsValue == atomic_val_compare_exchange_64(&pStatus->lastUpTs, lastTsValue, pCtx->currTs)) {
6,012!
700
        mstDebug("vgroup %d lastUpTs updated to %" PRId64, vgId, pCtx->currTs);
6,012✔
701
        return;
6,012✔
702
      }
703

UNCOV
704
      continue;
×
705
    }
706

707
    return;
103✔
708
  }  
709
}
710

711
int32_t msmUpdateVgroupsUpTs(SStmGrpCtx* pCtx) {
43,799✔
712
  int32_t code = TSDB_CODE_SUCCESS;
43,799✔
713
  int32_t lino = 0;
43,799✔
714
  int32_t vgNum = taosArrayGetSize(pCtx->pReq->pVgLeaders);
43,799✔
715

716
  mstDebug("start to update vgroups upTs");
43,799✔
717
  
718
  for (int32_t i = 0; i < vgNum; ++i) {
268,072✔
719
    int32_t* vgId = taosArrayGet(pCtx->pReq->pVgLeaders, i);
224,273✔
720

721
    msmUpdateVgroupUpTs(pCtx, *vgId);
224,273✔
722
  }
723

724
_exit:
43,799✔
725

726
  if (code) {
43,799!
UNCOV
727
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
728
  }
729

730
  return code;
43,799✔
731
}
732

733

734

735
void* msmSearchCalcCacheScanPlan(SArray* pList) {
414✔
736
  int32_t num = taosArrayGetSize(pList);
414✔
737
  for (int32_t i = 0; i < num; ++i) {
657✔
738
    SStreamCalcScan* pScan = taosArrayGet(pList, i);
461✔
739
    if (pScan->readFromCache) {
461✔
740
      return pScan->scanPlan;
218✔
741
    }
742
  }
743

744
  return NULL;
196✔
745
}
746

747
int32_t msmBuildReaderDeployInfo(SStmTaskDeploy* pDeploy, void* calcScanPlan, SStmStatus* pInfo, bool triggerReader) {
498✔
748
  SStreamReaderDeployMsg* pMsg = &pDeploy->msg.reader;
498✔
749
  pMsg->triggerReader = triggerReader;
498✔
750
  
751
  if (triggerReader) {
498✔
752
    SStreamReaderDeployFromTrigger* pTrigger = &pMsg->msg.trigger;
333✔
753
    pTrigger->triggerTblName = pInfo->pCreate->triggerTblName;
333✔
754
    pTrigger->triggerTblUid = pInfo->pCreate->triggerTblUid;
333✔
755
    pTrigger->triggerTblType = pInfo->pCreate->triggerTblType;
333✔
756
    pTrigger->deleteReCalc = pInfo->pCreate->deleteReCalc;
333✔
757
    pTrigger->deleteOutTbl = pInfo->pCreate->deleteOutTbl;
333✔
758
    pTrigger->partitionCols = pInfo->pCreate->partitionCols;
333✔
759
    pTrigger->triggerCols = pInfo->pCreate->triggerCols;
333✔
760
    //pTrigger->triggerPrevFilter = pStream->pCreate->triggerPrevFilter;
761
    pTrigger->triggerScanPlan = pInfo->pCreate->triggerScanPlan;
333✔
762
    pTrigger->calcCacheScanPlan = msmSearchCalcCacheScanPlan(pInfo->pCreate->calcScanPlanList);
333✔
763
  } else {
764
    SStreamReaderDeployFromCalc* pCalc = &pMsg->msg.calc;
165✔
765
    pCalc->execReplica = pInfo->runnerDeploys * pInfo->runnerReplica;
165✔
766
    pCalc->calcScanPlan = calcScanPlan;
165✔
767
  }
768

769
  return TSDB_CODE_SUCCESS;
498✔
770
}
771

772
int32_t msmBuildTriggerRunnerTargets(SMnode* pMnode, SStmStatus* pInfo, int64_t streamId, SArray** ppRes) {
271✔
773
  int32_t code = TSDB_CODE_SUCCESS;
271✔
774
  int32_t lino = 0;
271✔
775

776
  if (pInfo->runnerDeploys > 0) {
271!
777
    *ppRes = taosArrayInit(pInfo->runnerDeploys, sizeof(SStreamRunnerTarget));
271✔
778
    TSDB_CHECK_NULL(*ppRes, code, lino, _exit, terrno);
271!
779
  }
780
  
781
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
1,084✔
782
    SStmTaskStatus* pStatus = taosArrayGetLast(pInfo->runners[i]);
813✔
783
    TSDB_CHECK_NULL(pStatus, code, lino, _exit, terrno);
813!
784

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

800
_exit:
271✔
801

802
  if (code) {
271!
803
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
804
  }
805
  
806
  return TSDB_CODE_SUCCESS;
271✔
807
}
808

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

UNCOV
821
  mndReleaseSnode(pMnode, pSnode);
×
822

UNCOV
823
  pInfo->leaderEpSet = mndGetDnodeEpsetById(pMnode, pInfo->leaderSnodeId);
×
UNCOV
824
  if (GOT_SNODE(pInfo->replicaSnodeId)) {
×
UNCOV
825
    pInfo->replicaEpSet = mndGetDnodeEpsetById(pMnode, pInfo->replicaSnodeId);
×
826
  }
827

UNCOV
828
  return TSDB_CODE_SUCCESS;
×
829
}
830

831
int32_t msmBuildTriggerDeployInfo(SMnode* pMnode, SStmStatus* pInfo, SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
272✔
832
  int32_t code = TSDB_CODE_SUCCESS;
272✔
833
  int32_t lino = 0;
272✔
834
  int64_t streamId = pStream->pCreate->streamId;
272✔
835
  SStreamTriggerDeployMsg* pMsg = &pDeploy->msg.trigger;
272✔
836
  
837
  pMsg->triggerType = pStream->pCreate->triggerType;
272✔
838
  pMsg->igDisorder = pStream->pCreate->igDisorder;
272✔
839
  pMsg->fillHistory = pStream->pCreate->fillHistory;
272✔
840
  pMsg->fillHistoryFirst = pStream->pCreate->fillHistoryFirst;
272✔
841
  pMsg->lowLatencyCalc = pStream->pCreate->lowLatencyCalc;
272✔
842
  pMsg->igNoDataTrigger = pStream->pCreate->igNoDataTrigger;
272✔
843
  pMsg->hasPartitionBy = (pStream->pCreate->partitionCols != NULL);
272✔
844
  pMsg->isTriggerTblVirt = STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags);
272✔
845
  pMsg->triggerHasPF = pStream->pCreate->triggerHasPF;
272✔
846

847
  pMsg->pNotifyAddrUrls = pInfo->pCreate->pNotifyAddrUrls;
272✔
848
  pMsg->notifyEventTypes = pStream->pCreate->notifyEventTypes;
272✔
849
  pMsg->notifyErrorHandle = pStream->pCreate->notifyErrorHandle;
272✔
850
  pMsg->notifyHistory = pStream->pCreate->notifyHistory;
272✔
851

852
  pMsg->maxDelay = pStream->pCreate->maxDelay;
272✔
853
  pMsg->fillHistoryStartTime = pStream->pCreate->fillHistoryStartTime;
272✔
854
  pMsg->watermark = pStream->pCreate->watermark;
272✔
855
  pMsg->expiredTime = pStream->pCreate->expiredTime;
272✔
856
  pMsg->trigger = pInfo->pCreate->trigger;
272✔
857

858
  pMsg->eventTypes = pStream->pCreate->eventTypes;
272✔
859
  pMsg->placeHolderBitmap = pStream->pCreate->placeHolderBitmap;
272✔
860
  pMsg->calcTsSlotId = pStream->pCreate->calcTsSlotId;
272✔
861
  pMsg->triTsSlotId = pStream->pCreate->triTsSlotId;
272✔
862
  pMsg->triggerPrevFilter = pInfo->pCreate->triggerPrevFilter;
272✔
863
  if (STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags)) {
272✔
864
    pMsg->triggerScanPlan = pInfo->pCreate->triggerScanPlan;
81✔
865
    pMsg->calcCacheScanPlan = msmSearchCalcCacheScanPlan(pInfo->pCreate->calcScanPlanList);
81✔
866
  }
867

868
  SStreamTaskAddr addr;
869
  int32_t triggerReaderNum = taosArrayGetSize(pInfo->trigReaders);
272✔
870
  if (triggerReaderNum > 0) {
272✔
871
    pMsg->readerList = taosArrayInit(triggerReaderNum, sizeof(SStreamTaskAddr));
271✔
872
    TSDB_CHECK_NULL(pMsg->readerList, code, lino, _exit, terrno);
271!
873
  }
874
  
875
  for (int32_t i = 0; i < triggerReaderNum; ++i) {
554✔
876
    SStmTaskStatus* pStatus = taosArrayGet(pInfo->trigReaders, i);
282✔
877
    addr.taskId = pStatus->id.taskId;
282✔
878
    addr.nodeId = pStatus->id.nodeId;
282✔
879
    addr.epset = mndGetVgroupEpsetById(pMnode, pStatus->id.nodeId);
282✔
880
    TSDB_CHECK_NULL(taosArrayPush(pMsg->readerList, &addr), code, lino, _exit, terrno);
564!
881
    mstsDebug("the %dth trigReader src added to trigger's readerList, TASK:%" PRIx64 " nodeId:%d", i, addr.taskId, addr.nodeId);
282✔
882
  }
883

884
  pMsg->leaderSnodeId = pStream->mainSnodeId;
272✔
885
  pMsg->streamName = pInfo->streamName;
272✔
886

887
  if (0 == pInfo->runnerNum) {
272✔
888
    mstsDebug("no runner task, skip set trigger's runner list, deployNum:%d", pInfo->runnerDeploys);
1!
889
    return code;
1✔
890
  }
891

892
  TAOS_CHECK_EXIT(msmBuildTriggerRunnerTargets(pMnode, pInfo, streamId, &pMsg->runnerList));
271!
893

894
_exit:
271✔
895

896
  if (code) {
271!
UNCOV
897
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
898
  } else {
899
    mstsDebug("trigger deploy info built, readerNum:%d, runnerNum:%d", (int32_t)taosArrayGetSize(pMsg->readerList), (int32_t)taosArrayGetSize(pMsg->runnerList));
271✔
900
  }
901
  
902
  return TSDB_CODE_SUCCESS;
271✔
903
}
904

905

906
int32_t msmBuildRunnerDeployInfo(SStmTaskDeploy* pDeploy, SSubplan *plan, SStreamObj* pStream, SStmStatus* pInfo, bool topPlan) {
823✔
907
  int32_t code = TSDB_CODE_SUCCESS;
823✔
908
  int32_t lino = 0;
823✔
909
  int64_t streamId = pStream->pCreate->streamId;
823✔
910
  SStreamRunnerDeployMsg* pMsg = &pDeploy->msg.runner;
823✔
911
  //TAOS_CHECK_EXIT(qSubPlanToString(plan, &pMsg->pPlan, NULL));
912

913
  pMsg->execReplica = pInfo->runnerReplica;
823✔
914
  pMsg->streamName = pInfo->streamName;
823✔
915
  //TAOS_CHECK_EXIT(nodesCloneNode((SNode*)plan, (SNode**)&pMsg->pPlan));
916
  pMsg->pPlan = plan;
823✔
917
  pMsg->outDBFName = pInfo->pCreate->outDB;
823✔
918
  pMsg->outTblName = pInfo->pCreate->outTblName;
823✔
919
  pMsg->outTblType = pStream->pCreate->outTblType;
823✔
920
  pMsg->calcNotifyOnly = pStream->pCreate->calcNotifyOnly;
823✔
921
  pMsg->topPlan = topPlan;
823✔
922
  pMsg->pNotifyAddrUrls = pInfo->pCreate->pNotifyAddrUrls;
823✔
923
  pMsg->notifyErrorHandle = pStream->pCreate->notifyErrorHandle;
823✔
924
  pMsg->outCols = pInfo->pCreate->outCols;
823✔
925
  pMsg->outTags = pInfo->pCreate->outTags;
823✔
926
  pMsg->outStbUid = pStream->pCreate->outStbUid;
823✔
927
  pMsg->outStbSversion = pStream->pCreate->outStbSversion;
823✔
928
  
929
  pMsg->subTblNameExpr = pInfo->pCreate->subTblNameExpr;
823✔
930
  pMsg->tagValueExpr = pInfo->pCreate->tagValueExpr;
823✔
931
  pMsg->forceOutCols = pInfo->pCreate->forceOutCols;
823✔
932

933
_exit:
823✔
934

935
  if (code) {
823!
UNCOV
936
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
937
  }
938
  
939
  return code;
823✔
940
}
941

942

943
static int32_t msmSTAddToVgroupMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SStmTaskStatus* pTask, bool trigReader) {
581✔
944
  int32_t code = TSDB_CODE_SUCCESS;
581✔
945
  int32_t lino = 0;
581✔
946
  int32_t taskNum = pTask ? 1 : taosArrayGetSize(pTasks);
581✔
947
  
948
  for (int32_t i = 0; i < taskNum; ++i) {
1,051✔
949
    SStmTaskStatus* pStatus = pTask ? pTask : taosArrayGet(pTasks, i);
470✔
950
    TAOS_CHECK_EXIT(msmSTAddToVgroupMapImpl(streamId, pStatus, trigReader));
470!
951
  }
952
  
953
_exit:
581✔
954

955
  if (code) {
581!
UNCOV
956
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
957
  }
958
  
959
  return code;
581✔
960
}
961

962

963
static int32_t msmSTAddToSnodeMap(SStmGrpCtx* pCtx, int64_t streamId, SArray* pTasks, SStmTaskStatus* pTask, int32_t taskNum, int32_t deployId) {
1,095✔
964
  int32_t code = TSDB_CODE_SUCCESS;
1,095✔
965
  int32_t lino = 0;
1,095✔
966
  int32_t rtaskNum = (taskNum > 0) ? taskNum : taosArrayGetSize(pTasks);
1,095✔
967
  int32_t taskType = (deployId < 0) ? STREAM_TRIGGER_TASK : STREAM_RUNNER_TASK;
1,095✔
968
  
969
  for (int32_t i = 0; i < rtaskNum; ++i) {
2,190✔
970
    SStmTaskStatus* pStatus = (taskNum > 0) ? (pTask + i) : taosArrayGet(pTasks, i);
1,095✔
971
    TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pStatus, deployId));
1,095!
972
  }
973
  
974
_exit:
1,095✔
975

976
  if (code) {
1,095!
UNCOV
977
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
978
  }
979

980
  return code;
1,095✔
981
}
982

983
int64_t msmAssignTaskId(void) {
1,555✔
984
  return atomic_fetch_add_64(&mStreamMgmt.lastTaskId, 1);
1,555✔
985
}
986

987
int64_t msmAssignTaskSeriousId(void) {
1,555✔
988
  return taosGetTimestampNs();
1,555✔
989
}
990

991

992
int32_t msmIsSnodeAlive(SMnode* pMnode, int32_t snodeId, int64_t streamId, bool* alive) {
1,501✔
993
  int32_t code = TSDB_CODE_SUCCESS;
1,501✔
994
  int32_t lino = 0;
1,501✔
995
  bool     noExists = false;
1,501✔
996
  SStmSnodeStatus* pStatus = NULL;
1,501✔
997

998
  while (true) {
999
    pStatus = taosHashGet(mStreamMgmt.snodeMap, &snodeId, sizeof(snodeId));
1,520✔
1000
    if (NULL == pStatus) {
1,520✔
1001
      if (noExists) {
19!
UNCOV
1002
        mstsError("snode %d not exists in snodeMap", snodeId);
×
UNCOV
1003
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1004
      }
1005

1006
      noExists = true;
19✔
1007
      TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pMnode));
19!
1008
      
1009
      continue;
19✔
1010
    }
1011

1012
    *alive = (pStatus->runnerThreadNum >= 0);
1,501✔
1013
    break;
1,501✔
1014
  }
1015

1016
_exit:
1,501✔
1017

1018
  if (code) {
1,501!
UNCOV
1019
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1020
  }
1021

1022
  return code;
1,501✔
1023
}
1024

1025
int32_t msmRetrieveStaticSnodeId(SMnode* pMnode, SStreamObj* pStream) {
552✔
1026
  int32_t code = TSDB_CODE_SUCCESS;
552✔
1027
  int32_t lino = 0;
552✔
1028
  bool alive = false;
552✔
1029
  int32_t mainSnodeId = atomic_load_32(&pStream->mainSnodeId);
552✔
1030
  int32_t snodeId = mainSnodeId;
552✔
1031
  int64_t streamId = pStream->pCreate->streamId;
552✔
1032
  
1033
  while (true) {
1034
    TAOS_CHECK_EXIT(msmIsSnodeAlive(pMnode, snodeId, streamId, &alive));
552!
1035

1036
    if (alive) {
552!
1037
      return snodeId;
552✔
1038
    }
1039
    
UNCOV
1040
    if (snodeId == mainSnodeId) {
×
UNCOV
1041
      SSnodeObj* pSnode = mndAcquireSnode(pMnode, snodeId);
×
1042
      if (NULL == pSnode) {
×
1043
        stsWarn("snode %d not longer exists, ignore assign snode", snodeId);
×
UNCOV
1044
        return 0;
×
1045
      }
1046
      
UNCOV
1047
      if (pSnode->replicaId <= 0) {
×
1048
        mstsError("no available snode now, mainSnodeId:%d, replicaId:%d", mainSnodeId, pSnode->replicaId);
×
1049
        mndReleaseSnode(pMnode, pSnode);
×
UNCOV
1050
        return 0;
×
1051
      }
1052

UNCOV
1053
      snodeId = pSnode->replicaId;
×
1054
      mndReleaseSnode(pMnode, pSnode);
×
1055
      
UNCOV
1056
      continue;
×
1057
    }
1058

UNCOV
1059
    mstsError("no available snode now, mainSnodeId:%d, followerSnodeId:%d", mainSnodeId, snodeId);
×
UNCOV
1060
    return 0;
×
1061
  }
1062

UNCOV
1063
_exit:
×
1064

UNCOV
1065
  if (code) {
×
UNCOV
1066
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1067
  }
1068

UNCOV
1069
  return 0;
×
1070
}
1071

1072
int32_t msmAssignRandomSnodeId(SMnode* pMnode, int64_t streamId) {
845✔
1073
  int32_t code = TSDB_CODE_SUCCESS;
845✔
1074
  int32_t lino = 0;
845✔
1075
  int32_t snodeIdx = 0;
845✔
1076
  int32_t snodeId = 0;
845✔
1077
  void      *pIter = NULL;
845✔
1078
  SSnodeObj *pObj = NULL;
845✔
1079
  bool alive = false;
845✔
1080
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
845✔
1081
  if (snodeNum <= 0) {
845✔
1082
    mstsInfo("no available snode now, num:%d", snodeNum);
10!
1083
    goto _exit;
10✔
1084
  }
1085

1086
  int32_t snodeTarget = taosRand() % snodeNum;
835✔
1087

1088
  while (1) {
1089
    pIter = sdbFetch(pMnode->pSdb, SDB_SNODE, pIter, (void **)&pObj);
950✔
1090
    if (pIter == NULL) {
950✔
1091
      if (0 == snodeId) {
1!
1092
        mstsError("no alive snode now, snodeNum:%d", snodeNum);
×
1093
        break;
×
1094
      }
1095
      
1096
      snodeId = 0;
1✔
1097
      continue;
1✔
1098
    }
1099

1100
    code = msmIsSnodeAlive(pMnode, pObj->id, streamId, &alive);
949✔
1101
    if (code) {
949!
UNCOV
1102
      sdbRelease(pMnode->pSdb, pObj);
×
UNCOV
1103
      sdbCancelFetch(pMnode->pSdb, pIter);
×
UNCOV
1104
      pObj = NULL;
×
UNCOV
1105
      TAOS_CHECK_EXIT(code);
×
1106
    }
1107
    
1108
    if (!alive) {
949!
UNCOV
1109
      sdbRelease(pMnode->pSdb, pObj);
×
UNCOV
1110
      continue;
×
1111
    }
1112

1113
    snodeId = pObj->id;
949✔
1114
    if (snodeIdx == snodeTarget) {
949✔
1115
      sdbRelease(pMnode->pSdb, pObj);
835✔
1116
      sdbCancelFetch(pMnode->pSdb, pIter);
835✔
1117
      pObj = NULL;
835✔
1118
      goto _exit;
835✔
1119
    }
1120

1121
    sdbRelease(pMnode->pSdb, pObj);
114✔
1122
    snodeIdx++;
114✔
1123
  }
1124

1125
_exit:
845✔
1126

1127
  if (code) {
845!
UNCOV
1128
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1129
  }
1130

1131
  if (0 == snodeId) {
845✔
1132
    terrno = TSDB_CODE_SNODE_NO_AVAILABLE_NODE;
10✔
1133
  }
1134

1135
  return snodeId;
845✔
1136
}
1137

1138
int32_t msmAssignTaskSnodeId(SMnode* pMnode, SStreamObj* pStream, bool isStatic) {
1,095✔
1139
  int64_t streamId = pStream->pCreate->streamId;
1,095✔
1140
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
1,095✔
1141
  int32_t snodeId = 0;
1,095✔
1142
  if (snodeNum <= 0) {
1,095!
UNCOV
1143
    mstsInfo("no available snode now, num:%d", snodeNum);
×
UNCOV
1144
    goto _exit;
×
1145
  }
1146

1147
  snodeId = isStatic ? msmRetrieveStaticSnodeId(pMnode, pStream) : msmAssignRandomSnodeId(pMnode, streamId);
1,095✔
1148

1149
_exit:
1,095✔
1150

1151
  if (0 == snodeId) {
1,095!
UNCOV
1152
    terrno = TSDB_CODE_SNODE_NO_AVAILABLE_NODE;
×
1153
  }
1154

1155
  return snodeId;
1,095✔
1156
}
1157

1158

1159
static int32_t msmBuildTriggerTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
272✔
1160
  int32_t code = TSDB_CODE_SUCCESS;
272✔
1161
  int32_t lino = 0;
272✔
1162
  int64_t streamId = pStream->pCreate->streamId;
272✔
1163

1164
  pInfo->triggerTask = taosMemoryCalloc(1, sizeof(SStmTaskStatus));
272!
1165
  TSDB_CHECK_NULL(pInfo->triggerTask, code, lino, _exit, terrno);
272!
1166

1167
  pInfo->triggerTask->id.taskId = pCtx->triggerTaskId;
272✔
1168
  pInfo->triggerTask->id.deployId = 0;
272✔
1169
  pInfo->triggerTask->id.seriousId = msmAssignTaskSeriousId();
272✔
1170
  pInfo->triggerTask->id.nodeId = pCtx->triggerNodeId;
272✔
1171
  pInfo->triggerTask->id.taskIdx = 0;
272✔
1172
  pInfo->triggerTask->type = STREAM_TRIGGER_TASK;
272✔
1173
  pInfo->triggerTask->lastUpTs = pCtx->currTs;
272✔
1174
  pInfo->triggerTask->pStream = pInfo;
272✔
1175

1176
  SStmTaskDeploy info = {0};
272✔
1177
  info.task.type = pInfo->triggerTask->type;
272✔
1178
  info.task.streamId = streamId;
272✔
1179
  info.task.taskId =  pInfo->triggerTask->id.taskId;
272✔
1180
  info.task.seriousId = pInfo->triggerTask->id.seriousId;
272✔
1181
  info.task.nodeId =  pInfo->triggerTask->id.nodeId;
272✔
1182
  info.task.taskIdx =  pInfo->triggerTask->id.taskIdx;
272✔
1183
  TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pInfo, &info, pStream));
272!
1184
  TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
272!
1185
  
1186
  atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
272✔
1187

1188
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, pInfo->triggerTask));
272!
1189
  TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, pInfo->triggerTask, 1, -1));
272!
1190

1191
_exit:
272✔
1192

1193
  if (code) {
272!
UNCOV
1194
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1195
  }
1196

1197
  return code;
272✔
1198
}
1199

1200
static int32_t msmTDAddSingleTrigReader(SStmGrpCtx* pCtx, SStmTaskStatus* pState, int32_t nodeId, SStmStatus* pInfo, SStreamObj* pStream, int64_t streamId) {
319✔
1201
  int32_t code = TSDB_CODE_SUCCESS;
319✔
1202
  int32_t lino = 0;
319✔
1203

1204
  pState->id.taskId = msmAssignTaskId();
319✔
1205
  pState->id.deployId = 0;
319✔
1206
  pState->id.seriousId = msmAssignTaskSeriousId();
319✔
1207
  pState->id.nodeId = nodeId;
319✔
1208
  pState->id.taskIdx = 0;
319✔
1209
  pState->type = STREAM_READER_TASK;
319✔
1210
  pState->flags = STREAM_FLAG_TRIGGER_READER;
319✔
1211
  pState->status = STREAM_STATUS_UNDEPLOYED;
319✔
1212
  pState->lastUpTs = pCtx->currTs;
319✔
1213
  pState->pStream = pInfo;
319✔
1214
  
1215
  SStmTaskDeploy info = {0};
319✔
1216
  info.task.type = pState->type;
319✔
1217
  info.task.streamId = streamId;
319✔
1218
  info.task.taskId = pState->id.taskId;
319✔
1219
  info.task.flags = pState->flags;
319✔
1220
  info.task.seriousId = pState->id.seriousId;
319✔
1221
  info.task.nodeId = pState->id.nodeId;
319✔
1222
  info.task.taskIdx = pState->id.taskIdx;
319✔
1223
  TAOS_CHECK_EXIT(msmBuildReaderDeployInfo(&info, NULL, pInfo, true));
319!
1224
  TAOS_CHECK_EXIT(msmTDAddToVgroupMap(mStreamMgmt.toDeployVgMap, &info, streamId));
319!
1225

1226
_exit:
319✔
1227

1228
  if (code) {
319!
UNCOV
1229
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1230
  }
1231

1232
  return code;
319✔
1233
}
1234

1235
static int32_t msmTDAddTrigReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
272✔
1236
  int32_t code = TSDB_CODE_SUCCESS;
272✔
1237
  int32_t lino = 0;
272✔
1238
  int64_t streamId = pStream->pCreate->streamId;
272✔
1239
  SSdb   *pSdb = pCtx->pMnode->pSdb;
272✔
1240
  SStmTaskStatus* pState = NULL;
272✔
1241
  SVgObj *pVgroup = NULL;
272✔
1242
  SDbObj* pDb = NULL;
272✔
1243
  
1244
  switch (pStream->pCreate->triggerTblType) {
272✔
1245
    case TSDB_NORMAL_TABLE:
113✔
1246
    case TSDB_CHILD_TABLE:
1247
    case TSDB_VIRTUAL_CHILD_TABLE:
1248
    case TSDB_VIRTUAL_NORMAL_TABLE: {
1249
      pInfo->trigReaders = taosArrayInit_s(sizeof(SStmTaskStatus), 1);
113✔
1250
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
113!
1251
      pState = taosArrayGet(pInfo->trigReaders, 0);
113✔
1252
      
1253
      TAOS_CHECK_EXIT(msmTDAddSingleTrigReader(pCtx, pState, pStream->pCreate->triggerTblVgId, pInfo, pStream, streamId));
113!
1254
      break;
113✔
1255
    }
1256
    case TSDB_SUPER_TABLE: {
158✔
1257
      pDb = mndAcquireDb(pCtx->pMnode, pStream->pCreate->triggerDB);
158✔
1258
      if (NULL == pDb) {
158!
UNCOV
1259
        code = terrno;
×
UNCOV
1260
        mstsError("failed to acquire db %s, error:%s", pStream->pCreate->triggerDB, terrstr());
×
UNCOV
1261
        goto _exit;
×
1262
      }
1263

1264
      pInfo->trigReaders = taosArrayInit(pDb->cfg.numOfVgroups, sizeof(SStmTaskStatus));
158✔
1265
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
158!
1266
      
1267
      void *pIter = NULL;
158✔
1268
      while (1) {
725✔
1269
        SStmTaskDeploy info = {0};
883✔
1270
        pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
883✔
1271
        if (pIter == NULL) {
883✔
1272
          break;
158✔
1273
        }
1274
      
1275
        if (pVgroup->dbUid == pDb->uid && !pVgroup->isTsma) {
725!
1276
          pState = taosArrayReserve(pInfo->trigReaders, 1);
169✔
1277

1278
          code = msmTDAddSingleTrigReader(pCtx, pState, pVgroup->vgId, pInfo, pStream, streamId);
169✔
1279
          if (code) {
169!
UNCOV
1280
            sdbRelease(pSdb, pVgroup);
×
UNCOV
1281
            sdbCancelFetch(pSdb, pIter);
×
UNCOV
1282
            pVgroup = NULL;
×
UNCOV
1283
            TAOS_CHECK_EXIT(code);
×
1284
          }
1285
        }
1286

1287
        sdbRelease(pSdb, pVgroup);
725✔
1288
      }
1289
      break;
158✔
1290
    }
1291
    default:
1✔
1292
      mstsDebug("%s ignore triggerTblType %d", __FUNCTION__, pStream->pCreate->triggerTblType);
1!
1293
      break;
1✔
1294
  }
1295

1296
_exit:
272✔
1297

1298
  mndReleaseDb(pCtx->pMnode, pDb);
272✔
1299

1300
  if (code) {
272!
UNCOV
1301
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1302
  }
1303

1304
  return code;
272✔
1305
}
1306

1307
int32_t msmUPAddScanTask(SStmGrpCtx* pCtx, SStreamObj* pStream, char* scanPlan, int32_t vgId, int64_t taskId) {
160✔
1308
  int32_t code = TSDB_CODE_SUCCESS;
160✔
1309
  int32_t lino = 0;
160✔
1310
  SSubplan* pSubplan = NULL;
160✔
1311
  int64_t streamId = pStream->pCreate->streamId;
160✔
1312
  int64_t key[2] = {streamId, 0};
160✔
1313
  SStmTaskSrcAddr addr;
1314
  TAOS_CHECK_EXIT(nodesStringToNode(scanPlan, (SNode**)&pSubplan));
160!
1315
  addr.isFromCache = false;
160✔
1316
  
1317
  if (MNODE_HANDLE == vgId) {
160!
UNCOV
1318
    mndGetMnodeEpSet(pCtx->pMnode, &addr.epset);
×
1319
  } else if (vgId > MNODE_HANDLE) {
160!
1320
    addr.epset = mndGetVgroupEpsetById(pCtx->pMnode, vgId);
160✔
1321
  } else {
UNCOV
1322
    mstsError("invalid vgId %d in scanPlan", vgId);
×
UNCOV
1323
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1324
  }
1325
  
1326
  addr.taskId = taskId;
160✔
1327
  addr.vgId = vgId;
160✔
1328
  addr.groupId = pSubplan->id.groupId;
160✔
1329

1330
  key[1] = pSubplan->id.subplanId;
160✔
1331

1332
  SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
160✔
1333
  if (NULL == ppRes) {
160!
1334
    SArray* pRes = taosArrayInit(1, sizeof(addr));
160✔
1335
    TSDB_CHECK_NULL(pRes, code, lino, _exit, terrno);
160!
1336
    TSDB_CHECK_NULL(taosArrayPush(pRes, &addr), code, lino, _exit, terrno);
320!
1337
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.toUpdateScanMap, key, sizeof(key), &pRes, POINTER_BYTES));
160!
1338
  } else {
UNCOV
1339
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &addr), code, lino, _exit, terrno);
×
1340
  }
1341

1342
  mstsDebug("calcReader %" PRIx64 " added to toUpdateScan, vgId:%d, groupId:%d, subplanId:%d", taskId, vgId, pSubplan->id.groupId, pSubplan->id.subplanId);
160✔
1343
  
1344
  atomic_add_fetch_32(&mStreamMgmt.toUpdateScanNum, 1);
160✔
1345
  
1346
_exit:
160✔
1347

1348
  nodesDestroyNode((SNode*)pSubplan);
160✔
1349

1350
  if (code) {
160!
UNCOV
1351
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1352
  }
1353

1354
  return code;
160✔
1355
}
1356

1357
int32_t msmUPAddCacheTask(SStmGrpCtx* pCtx, SStreamCalcScan* pScan, SStreamObj* pStream) {
144✔
1358
  int32_t code = TSDB_CODE_SUCCESS;
144✔
1359
  int32_t lino = 0;
144✔
1360
  SSubplan* pSubplan = NULL;
144✔
1361
  int64_t streamId = pStream->pCreate->streamId;
144✔
1362
  int64_t key[2] = {streamId, 0};
144✔
1363
  TAOS_CHECK_EXIT(nodesStringToNode(pScan->scanPlan, (SNode**)&pSubplan));
144!
1364

1365
  SStmTaskSrcAddr addr;
1366
  addr.isFromCache = true;
144✔
1367
  addr.epset = mndGetDnodeEpsetById(pCtx->pMnode, pCtx->triggerNodeId);
144✔
1368
  addr.taskId = pCtx->triggerTaskId;
144✔
1369
  addr.vgId = pCtx->triggerNodeId;
144✔
1370
  addr.groupId = pSubplan->id.groupId;
144✔
1371

1372
  key[1] = pSubplan->id.subplanId;
144✔
1373
  SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
144✔
1374
  if (NULL == ppRes) {
144!
1375
    SArray* pRes = taosArrayInit(1, sizeof(addr));
144✔
1376
    TSDB_CHECK_NULL(pRes, code, lino, _exit, terrno);
144!
1377
    TSDB_CHECK_NULL(taosArrayPush(pRes, &addr), code, lino, _exit, terrno);
288!
1378
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.toUpdateScanMap, key, sizeof(key), &pRes, POINTER_BYTES));
144!
1379
  } else {
UNCOV
1380
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &addr), code, lino, _exit, terrno);
×
1381
  }
1382
  
1383
  atomic_add_fetch_32(&mStreamMgmt.toUpdateScanNum, 1);
144✔
1384
  
1385
_exit:
144✔
1386

1387
  nodesDestroyNode((SNode*)pSubplan);
144✔
1388
  
1389
  if (code) {
144!
UNCOV
1390
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1391
  }
1392

1393
  return code;
144✔
1394
}
1395

1396

1397
static int32_t msmTDAddCalcReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
272✔
1398
  int32_t code = TSDB_CODE_SUCCESS;
272✔
1399
  int32_t lino = 0;
272✔
1400
  int32_t calcTasksNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
272✔
1401
  int64_t streamId = pStream->pCreate->streamId;
272✔
1402
  SStmTaskStatus* pState = NULL;
272✔
1403
  pInfo->calcReaders = taosArrayInit(calcTasksNum, sizeof(SStmTaskStatus));
272✔
1404
  TSDB_CHECK_NULL(pInfo->calcReaders, code, lino, _exit, terrno);
272!
1405
  
1406
  for (int32_t i = 0; i < calcTasksNum; ++i) {
567✔
1407
    SStreamCalcScan* pScan = taosArrayGet(pInfo->pCreate->calcScanPlanList, i);
295✔
1408
    if (pScan->readFromCache) {
295✔
1409
      TAOS_CHECK_EXIT(msmUPAddCacheTask(pCtx, pScan, pStream));
144!
1410
      continue;
144✔
1411
    }
1412
    
1413
    int32_t vgNum = taosArrayGetSize(pScan->vgList);
151✔
1414
    for (int32_t m = 0; m < vgNum; ++m) {
302✔
1415
      pState = taosArrayReserve(pInfo->calcReaders, 1);
151✔
1416

1417
      pState->id.taskId = msmAssignTaskId();
151✔
1418
      pState->id.deployId = 0;
151✔
1419
      pState->id.seriousId = msmAssignTaskSeriousId();
151✔
1420
      pState->id.nodeId = *(int32_t*)taosArrayGet(pScan->vgList, m);
151✔
1421
      pState->id.taskIdx = i;
151✔
1422
      pState->type = STREAM_READER_TASK;
151✔
1423
      pState->flags = 0;
151✔
1424
      pState->status = STREAM_STATUS_UNDEPLOYED;
151✔
1425
      pState->lastUpTs = pCtx->currTs;
151✔
1426
      pState->pStream = pInfo;
151✔
1427

1428
      SStmTaskDeploy info = {0};
151✔
1429
      info.task.type = pState->type;
151✔
1430
      info.task.streamId = streamId;
151✔
1431
      info.task.taskId = pState->id.taskId;
151✔
1432
      info.task.flags = pState->flags;
151✔
1433
      info.task.seriousId = pState->id.seriousId;
151✔
1434
      info.task.nodeId = pState->id.nodeId;
151✔
1435
      info.task.taskIdx = pState->id.taskIdx;
151✔
1436
      TAOS_CHECK_EXIT(msmBuildReaderDeployInfo(&info, pScan->scanPlan, pInfo, false));
151!
1437
      TAOS_CHECK_EXIT(msmUPAddScanTask(pCtx, pStream, pScan->scanPlan, pState->id.nodeId, pState->id.taskId));
151!
1438
      TAOS_CHECK_EXIT(msmTDAddToVgroupMap(mStreamMgmt.toDeployVgMap, &info, streamId));
151!
1439
    }
1440
  }
1441

1442
_exit:
272✔
1443

1444
  if (code) {
272!
UNCOV
1445
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1446
  }
1447

1448
  return code;
272✔
1449
}
1450

1451

1452

1453
static int32_t msmUPPrepareReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
9✔
1454
  int32_t code = TSDB_CODE_SUCCESS;
9✔
1455
  int32_t lino = 0;
9✔
1456
  int64_t streamId = pStream->pCreate->streamId;
9✔
1457
  int32_t calcTasksNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
9✔
1458
  if (calcTasksNum <= 0) {
9!
UNCOV
1459
    mstsDebug("no calc scan plan, ignore parepare reader tasks, readerNum:%d", (int32_t)taosArrayGetSize(pInfo->calcReaders));
×
UNCOV
1460
    return code;    
×
1461
  }
1462
  
1463
  SStmTaskStatus* pReader = taosArrayGet(pInfo->calcReaders, 0);
9✔
1464
  
1465
  for (int32_t i = 0; i < calcTasksNum; ++i) {
18✔
1466
    SStreamCalcScan* pScan = taosArrayGet(pStream->pCreate->calcScanPlanList, i);
9✔
1467
    if (pScan->readFromCache) {
9!
UNCOV
1468
      TAOS_CHECK_EXIT(msmUPAddCacheTask(pCtx, pScan, pStream));
×
UNCOV
1469
      continue;
×
1470
    }
1471
    
1472
    int32_t vgNum = taosArrayGetSize(pScan->vgList);
9✔
1473
    for (int32_t m = 0; m < vgNum; ++m) {
18✔
1474
      TAOS_CHECK_EXIT(msmUPAddScanTask(pCtx, pStream, pScan->scanPlan, pReader->id.nodeId, pReader->id.taskId));
9!
1475
      pReader++;
9✔
1476
    }
1477
  }
1478

1479
_exit:
9✔
1480

1481
  if (code) {
9!
UNCOV
1482
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1483
  }
1484

1485
  return code;
9✔
1486
}
1487

1488
static int32_t msmBuildReaderTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
272✔
1489
  int32_t code = TSDB_CODE_SUCCESS;
272✔
1490
  int32_t lino = 0;
272✔
1491
  int64_t streamId = pStream->pCreate->streamId;
272✔
1492
  
1493
  TAOS_CHECK_EXIT(msmTDAddTrigReaderTasks(pCtx, pInfo, pStream));
272!
1494
  TAOS_CHECK_EXIT(msmTDAddCalcReaderTasks(pCtx, pInfo, pStream));
272!
1495

1496
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, pInfo->trigReaders, NULL));
272!
1497
  TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, pInfo->calcReaders, NULL));
272!
1498
  
1499
  TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, pInfo->trigReaders, NULL, true));
272!
1500
  TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, pInfo->calcReaders, NULL, false));
272!
1501
  
1502
_exit:
272✔
1503

1504
  if (code) {
272!
UNCOV
1505
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1506
  }
1507
  
1508
  return code;
272✔
1509
}
1510

1511
int32_t msmUpdatePlanSourceAddr(SStreamTask* pTask, int64_t streamId, SSubplan* plan, int64_t clientId, SStmTaskSrcAddr* pSrc, int32_t msgType, int64_t srcSubplanId) {
895✔
1512
  SDownstreamSourceNode source = {
895✔
1513
      .type = QUERY_NODE_DOWNSTREAM_SOURCE,
1514
      .clientId = clientId,
1515
      .taskId = pSrc->taskId,
895✔
1516
      .sId = 0,
1517
      .execId = 0,
1518
      .fetchMsgType = msgType,
1519
      .localExec = false,
1520
  };
1521

1522
  source.addr.epSet = pSrc->epset;
895✔
1523
  source.addr.nodeId = pSrc->vgId;
895✔
1524

1525
  msttDebug("try to update subplan %d grp %d sourceAddr from subplan %" PRId64 ", clientId:%" PRIx64 ", srcTaskId:%" PRIx64 ", srcNodeId:%d, msgType:%s", 
895!
1526
      plan->id.subplanId, pSrc->groupId, srcSubplanId, source.clientId, source.taskId, source.addr.nodeId, TMSG_INFO(source.fetchMsgType));
1527
  
1528
  return qSetSubplanExecutionNode(plan, pSrc->groupId, &source);
895✔
1529
}
1530

UNCOV
1531
int32_t msmGetTaskIdFromSubplanId(SStreamObj* pStream, SArray* pRunners, int32_t beginIdx, int32_t subplanId, int64_t* taskId, SStreamTask** ppParent) {
×
UNCOV
1532
  int64_t streamId = pStream->pCreate->streamId;
×
1533
  int32_t runnerNum = taosArrayGetSize(pRunners);
×
UNCOV
1534
  for (int32_t i = beginIdx; i < runnerNum; ++i) {
×
1535
    SStmTaskDeploy* pDeploy = taosArrayGet(pRunners, i);
×
UNCOV
1536
    SSubplan* pPlan = pDeploy->msg.runner.pPlan;
×
UNCOV
1537
    if (pPlan->id.subplanId == subplanId) {
×
UNCOV
1538
      *taskId = pDeploy->task.taskId;
×
UNCOV
1539
      *ppParent = &pDeploy->task;
×
UNCOV
1540
      return TSDB_CODE_SUCCESS;
×
1541
    }
1542
  }
1543

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

1546
  return TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
1547
}
1548

1549
int32_t msmUpdateLowestPlanSourceAddr(SSubplan* pPlan, SStmTaskDeploy* pDeploy, int64_t streamId) {
823✔
1550
  int32_t code = TSDB_CODE_SUCCESS;
823✔
1551
  int32_t lino = 0;
823✔
1552
  int64_t key[2] = {streamId, -1};
823✔
1553
  SNode* pNode = NULL;
823✔
1554
  SStreamTask* pTask = &pDeploy->task;
823✔
1555
  FOREACH(pNode, pPlan->pChildren) {
1,718!
1556
    if (QUERY_NODE_VALUE != nodeType(pNode)) {
895!
UNCOV
1557
      msttDebug("node type %d is not valueNode, skip it", nodeType(pNode));
×
UNCOV
1558
      continue;
×
1559
    }
1560
    
1561
    SValueNode* pVal = (SValueNode*)pNode;
895✔
1562
    if (TSDB_DATA_TYPE_BIGINT != pVal->node.resType.type) {
895!
UNCOV
1563
      msttWarn("invalid value node data type %d for runner's child subplan", pVal->node.resType.type);
×
UNCOV
1564
      continue;
×
1565
    }
1566

1567
    key[1] = MND_GET_RUNNER_SUBPLANID(pVal->datum.i);
895✔
1568

1569
    SArray** ppRes = taosHashGet(mStreamMgmt.toUpdateScanMap, key, sizeof(key));
895✔
1570
    if (NULL == ppRes) {
895!
UNCOV
1571
      msttError("lowest runner subplan ID:%d,%d can't get its child ID:%" PRId64 " addr", pPlan->id.groupId, pPlan->id.subplanId, key[1]);
×
UNCOV
1572
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1573
    }
1574

1575
    int32_t childrenNum = taosArrayGetSize(*ppRes);
895✔
1576
    for (int32_t i = 0; i < childrenNum; ++i) {
1,790✔
1577
      SStmTaskSrcAddr* pAddr = taosArrayGet(*ppRes, i);
895✔
1578
      TAOS_CHECK_EXIT(msmUpdatePlanSourceAddr(pTask, streamId, pPlan, pDeploy->task.taskId, pAddr, pAddr->isFromCache ? TDMT_STREAM_FETCH_FROM_CACHE : TDMT_STREAM_FETCH, key[1]));
895!
1579
    }
1580
  }
1581

1582
_exit:
823✔
1583

1584
  if (code) {
823!
UNCOV
1585
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1586
  }
1587

1588
  return code;
823✔
1589
}
1590

1591
int32_t msmUpdateRunnerPlan(SStmGrpCtx* pCtx, SArray* pRunners, int32_t beginIdx, SStmTaskDeploy* pDeploy, SStreamObj* pStream) {
823✔
1592
  int32_t code = TSDB_CODE_SUCCESS;
823✔
1593
  int32_t lino = 0;
823✔
1594
  SSubplan* pPlan = pDeploy->msg.runner.pPlan;
823✔
1595
  SStreamTask* pTask = &pDeploy->task;
823✔
1596
  SStreamTask* parentTask = NULL;
823✔
1597
  int64_t streamId = pStream->pCreate->streamId;
823✔
1598

1599
  TAOS_CHECK_EXIT(msmUpdateLowestPlanSourceAddr(pPlan, pDeploy, streamId));
823!
1600

1601
  SNode* pTmp = NULL;
823✔
1602
  WHERE_EACH(pTmp, pPlan->pChildren) {
1,718!
1603
    if (QUERY_NODE_VALUE == nodeType(pTmp)) {
895!
1604
      ERASE_NODE(pPlan->pChildren);
895✔
1605
      continue;
895✔
1606
    }
1607
    WHERE_NEXT;
×
1608
  }
1609
  nodesClearList(pPlan->pChildren);
823✔
1610
  pPlan->pChildren = NULL;
823✔
1611

1612
  if (NULL == pPlan->pParents) {
823!
1613
    goto _exit;
823✔
1614
  }
1615

UNCOV
1616
  SNode* pNode = NULL;
×
UNCOV
1617
  int64_t parentTaskId = 0;
×
1618
  SStmTaskSrcAddr addr = {0};
×
UNCOV
1619
  addr.taskId = pDeploy->task.taskId;
×
UNCOV
1620
  addr.vgId = pDeploy->task.nodeId;
×
1621
  addr.groupId = pPlan->id.groupId;
×
UNCOV
1622
  addr.epset = mndGetDnodeEpsetById(pCtx->pMnode, pDeploy->task.nodeId);
×
UNCOV
1623
  FOREACH(pNode, pPlan->pParents) {
×
UNCOV
1624
    SSubplan* pSubplan = (SSubplan*)pNode;
×
UNCOV
1625
    TAOS_CHECK_EXIT(msmGetTaskIdFromSubplanId(pStream, pRunners, beginIdx, pSubplan->id.subplanId, &parentTaskId, &parentTask));
×
UNCOV
1626
    TAOS_CHECK_EXIT(msmUpdatePlanSourceAddr(parentTask, streamId, pSubplan, parentTaskId, &addr, TDMT_STREAM_FETCH_FROM_RUNNER, pPlan->id.subplanId));
×
1627
  }
1628
  
UNCOV
1629
_exit:
×
1630

1631
  if (code) {
823!
UNCOV
1632
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1633
  }
1634

1635
  return code;
823✔
1636
}
1637

1638
int32_t msmUpdateRunnerPlans(SStmGrpCtx* pCtx, SArray* pRunners, SStreamObj* pStream) {
823✔
1639
  int32_t code = TSDB_CODE_SUCCESS;
823✔
1640
  int32_t lino = 0;
823✔
1641
  int64_t streamId = pStream->pCreate->streamId;
823✔
1642
  int32_t runnerNum = taosArrayGetSize(pRunners);
823✔
1643
  
1644
  for (int32_t i = 0; i < runnerNum; ++i) {
1,646✔
1645
    SStmTaskDeploy* pDeploy = taosArrayGet(pRunners, i);
823✔
1646
    TAOS_CHECK_EXIT(msmUpdateRunnerPlan(pCtx, pRunners, i, pDeploy, pStream));
823!
1647
    TAOS_CHECK_EXIT(nodesNodeToString((SNode*)pDeploy->msg.runner.pPlan, false, (char**)&pDeploy->msg.runner.pPlan, NULL));
823!
1648

1649
    SStreamTask* pTask = &pDeploy->task;
823✔
1650
    msttDebugL("runner updated task plan:%s", (const char*)pDeploy->msg.runner.pPlan);
823✔
1651
  }
1652

1653
_exit:
823✔
1654

1655
  if (code) {
823!
UNCOV
1656
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1657
  }
1658

1659
  return code;
823✔
1660
}
1661

1662
int32_t msmBuildRunnerTasksImpl(SStmGrpCtx* pCtx, SQueryPlan* pDag, SStmStatus* pInfo, SStreamObj* pStream) {
271✔
1663
  int32_t code = 0;
271✔
1664
  int32_t lino = 0;
271✔
1665
  int64_t streamId = pStream->pCreate->streamId;
271✔
1666
  SArray* deployTaskList = NULL;
271✔
1667
  SArray* deployList = NULL;
271✔
1668
  int32_t deployNodeId = 0;
271✔
1669
  SStmTaskStatus* pState = NULL;
271✔
1670
  int32_t taskIdx = 0;
271✔
1671
  SNodeListNode *plans = NULL;
271✔
1672
  int32_t        taskNum = 0;
271✔
1673
  int32_t        totalTaskNum = 0;
271✔
1674

1675
  if (pDag->numOfSubplans <= 0) {
271!
1676
    mstsError("invalid subplan num:%d", pDag->numOfSubplans);
×
1677
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1678
  }
1679

1680
  if (pDag->numOfSubplans != pStream->pCreate->numOfCalcSubplan) {
271!
UNCOV
1681
    mstsError("numOfCalcSubplan %d mismatch with numOfSubplans %d", pStream->pCreate->numOfCalcSubplan, pDag->numOfSubplans);
×
UNCOV
1682
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1683
  }
1684

1685
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
271!
1686
  if (levelNum <= 0) {
271!
UNCOV
1687
    mstsError("invalid level num:%d", levelNum);
×
UNCOV
1688
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1689
  }
1690

1691
  int32_t        lowestLevelIdx = levelNum - 1;
271✔
1692
  
1693
  plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, 0);
271✔
1694
  if (QUERY_NODE_NODE_LIST != nodeType(plans)) {
271!
UNCOV
1695
    mstsError("invalid level plan, level:0, planNodeType:%d", nodeType(plans));
×
UNCOV
1696
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1697
  }
1698
  
1699
  taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
271!
1700
  if (taskNum != 1) {
271!
UNCOV
1701
    mstsError("invalid level plan number:%d, level:0", taskNum);
×
UNCOV
1702
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1703
  }
1704

1705
  deployTaskList = taosArrayInit_s(sizeof(SStmTaskDeploy), pDag->numOfSubplans);
271✔
1706
  TSDB_CHECK_NULL(deployTaskList, code, lino, _exit, terrno);
271!
1707
  
1708
  for (int32_t deployId = 0; deployId < pInfo->runnerDeploys; ++deployId) {
1,084✔
1709
    totalTaskNum = 0;
813✔
1710

1711
    deployList = pInfo->runners[deployId];
813✔
1712
    deployNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, (0 == deployId) ? true : false);
813✔
1713
    if (!GOT_SNODE(deployNodeId)) {
813!
UNCOV
1714
      TAOS_CHECK_EXIT(terrno);
×
1715
    }
1716

1717
    taskIdx = 0;
813✔
1718
    
1719
    for (int32_t i = lowestLevelIdx; i >= 0; --i) {
1,626✔
1720
      plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
813✔
1721
      if (NULL == plans) {
813!
1722
        mstsError("empty level plan, level:%d", i);
×
1723
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1724
      }
1725

1726
      if (QUERY_NODE_NODE_LIST != nodeType(plans)) {
813!
UNCOV
1727
        mstsError("invalid level plan, level:%d, planNodeType:%d", i, nodeType(plans));
×
1728
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1729
      }
1730

1731
      taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
813!
1732
      if (taskNum <= 0) {
813!
UNCOV
1733
        mstsError("invalid level plan number:%d, level:%d", taskNum, i);
×
UNCOV
1734
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1735
      }
1736

1737
      totalTaskNum += taskNum;
813✔
1738
      if (totalTaskNum > pDag->numOfSubplans) {
813!
UNCOV
1739
        mstsError("current totalTaskNum %d is bigger than numOfSubplans %d, level:%d", totalTaskNum, pDag->numOfSubplans, i);
×
UNCOV
1740
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1741
      }
1742

1743
      for (int32_t n = 0; n < taskNum; ++n) {
1,626✔
1744
        SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
813✔
1745
        pState = taosArrayReserve(deployList, 1);
813✔
1746

1747
        pState->id.taskId = msmAssignTaskId();
813✔
1748
        pState->id.deployId = deployId;
813✔
1749
        pState->id.seriousId = msmAssignTaskSeriousId();
813✔
1750
        pState->id.nodeId = deployNodeId;
813✔
1751
        pState->id.taskIdx = MND_SET_RUNNER_TASKIDX(i, n);
813✔
1752
        pState->type = STREAM_RUNNER_TASK;
813✔
1753
        pState->flags = (0 == i) ? STREAM_FLAG_TOP_RUNNER : 0;
813!
1754
        pState->status = STREAM_STATUS_UNDEPLOYED;
813✔
1755
        pState->lastUpTs = pCtx->currTs;
813✔
1756
        pState->pStream = pInfo;
813✔
1757

1758
        SStmTaskDeploy* pDeploy = taosArrayGet(deployTaskList, taskIdx++);
813✔
1759
        pDeploy->task.type = pState->type;
813✔
1760
        pDeploy->task.streamId = streamId;
813✔
1761
        pDeploy->task.taskId = pState->id.taskId;
813✔
1762
        pDeploy->task.flags = pState->flags;
813✔
1763
        pDeploy->task.seriousId = pState->id.seriousId;
813✔
1764
        pDeploy->task.deployId = pState->id.deployId;
813✔
1765
        pDeploy->task.nodeId = pState->id.nodeId;
813✔
1766
        pDeploy->task.taskIdx = pState->id.taskIdx;
813✔
1767
        TAOS_CHECK_EXIT(msmBuildRunnerDeployInfo(pDeploy, plan, pStream, pInfo, 0 == i));
813!
1768

1769
        SStreamTask* pTask = &pDeploy->task;
813✔
1770
        msttDebug("runner task deploy built, subplan level:%d, taskIdx:%d, groupId:%d, subplanId:%d",
813✔
1771
            i, pTask->taskIdx, plan->id.groupId, plan->id.subplanId);
1772
      }
1773

1774
      mstsDebug("deploy %d level %d initialized, taskNum:%d", deployId, i, taskNum);
813✔
1775
    }
1776

1777
    if (totalTaskNum != pDag->numOfSubplans) {
813!
UNCOV
1778
      mstsError("totalTaskNum %d mis-match with numOfSubplans %d", totalTaskNum, pDag->numOfSubplans);
×
UNCOV
1779
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
1780
    }
1781

1782
    TAOS_CHECK_EXIT(msmUpdateRunnerPlans(pCtx, deployTaskList, pStream));
813!
1783

1784
    TAOS_CHECK_EXIT(msmTDAddRunnersToSnodeMap(deployTaskList, pStream));
813!
1785

1786
    nodesDestroyNode((SNode *)pDag);
813✔
1787
    pDag = NULL;
813✔
1788
    
1789
    TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pDag));
813!
1790

1791
    mstsDebug("total %d runner tasks added for deploy %d", totalTaskNum, deployId);
813✔
1792
  }
1793

1794
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
1,084✔
1795
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, pInfo->runners[i], NULL));
813!
1796
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, pInfo->runners[i], NULL, 0, i));
813!
1797
  }
1798
  
1799
  pInfo->runnerNum = totalTaskNum;
271✔
1800
  
1801
_exit:
271✔
1802

1803
  if (code) {
271!
UNCOV
1804
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1805
  }
1806

1807
  taosArrayDestroy(deployTaskList);
271✔
1808
  nodesDestroyNode((SNode *)pDag);
271✔
1809

1810
  return code;
271✔
1811
}
1812

1813
int32_t msmReBuildRunnerTasks(SStmGrpCtx* pCtx, SQueryPlan* pDag, SStmStatus* pInfo, SStreamObj* pStream, SStmTaskAction* pAction) {
9✔
1814
  int32_t code = 0;
9✔
1815
  int32_t lino = 0;
9✔
1816
  int64_t streamId = pStream->pCreate->streamId;
9✔
1817
  int32_t newNodeId = 0;
9✔
1818
  int32_t levelNum = (int32_t)LIST_LENGTH(pDag->pSubplans);
9!
1819
  int32_t        lowestLevelIdx = levelNum - 1;
9✔
1820
  SNodeListNode *plans = NULL;
9✔
1821
  int32_t        taskNum = 0;
9✔
1822
  int32_t        totalTaskNum = 0;
9✔
1823
  int32_t        deployId = 0;
9✔
1824
  SStmTaskStatus* pRunner = NULL;
9✔
1825
  SStmTaskStatus* pStartRunner = NULL;
9✔
1826
  int32_t taskIdx = 0;
9✔
1827
  SArray* deployTaskList = taosArrayInit_s(sizeof(SStmTaskDeploy), pDag->numOfSubplans);
9✔
1828
  TSDB_CHECK_NULL(deployTaskList, code, lino, _exit, terrno);
9!
1829

1830
  for (int32_t r = 0; r < pAction->deployNum; ++r) {
19✔
1831
    deployId = pAction->deployId[r];
10✔
1832

1833
    pRunner = taosArrayGet(pInfo->runners[deployId], 0);
10✔
1834

1835
    pStartRunner = pRunner;
10✔
1836
    totalTaskNum = 0;
10✔
1837

1838
    newNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, (0 == r) ? true : false);
10✔
1839
    if (!GOT_SNODE(newNodeId)) {
10!
UNCOV
1840
      TAOS_CHECK_EXIT(terrno);
×
1841
    }
1842

1843
    taskIdx = 0;
10✔
1844
    
1845
    for (int32_t i = lowestLevelIdx; i >= 0; --i) {
20✔
1846
      plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
10✔
1847
      taskNum = (int32_t)LIST_LENGTH(plans->pNodeList);
10!
1848
      totalTaskNum += taskNum;
10✔
1849

1850
      pRunner->flags &= STREAM_FLAG_REDEPLOY_RUNNER;
10✔
1851
      
1852
      for (int32_t n = 0; n < taskNum; ++n) {
20✔
1853
        SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
10✔
1854

1855
        int32_t newTaskIdx = MND_SET_RUNNER_TASKIDX(i, n);
10✔
1856
        if (pRunner->id.taskIdx != newTaskIdx) {
10!
UNCOV
1857
          mstsError("runner TASK:%" PRId64 " taskIdx %d mismatch with newTaskIdx:%d", pRunner->id.taskId, pRunner->id.taskIdx, newTaskIdx);
×
UNCOV
1858
          TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
1859
        }
1860

1861
        pRunner->id.nodeId = newNodeId;
10✔
1862

1863
        SStmTaskDeploy* pDeploy = taosArrayGet(deployTaskList, taskIdx++);
10✔
1864
        pDeploy->task.type = pRunner->type;
10✔
1865
        pDeploy->task.streamId = streamId;
10✔
1866
        pDeploy->task.taskId = pRunner->id.taskId;
10✔
1867
        pDeploy->task.flags = pRunner->flags;
10✔
1868
        pDeploy->task.seriousId = pRunner->id.seriousId;
10✔
1869
        pDeploy->task.nodeId = pRunner->id.nodeId;
10✔
1870
        pDeploy->task.taskIdx = pRunner->id.taskIdx;
10✔
1871
        TAOS_CHECK_EXIT(msmBuildRunnerDeployInfo(pDeploy, plan, pStream, pInfo, 0 == i));
10!
1872

1873
        pRunner++;
10✔
1874
      }
1875

1876
      mstsDebug("level %d initialized, taskNum:%d", i, taskNum);
10!
1877
    }
1878

1879
    TAOS_CHECK_EXIT(msmUpdateRunnerPlans(pCtx, deployTaskList, pStream));
10!
1880

1881
    TAOS_CHECK_EXIT(msmTDAddRunnersToSnodeMap(deployTaskList, pStream));
10!
1882

1883
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, pInfo->runners[deployId], NULL, 0, deployId));
10!
1884

1885
    nodesDestroyNode((SNode *)pDag);
10✔
1886
    pDag = NULL;
10✔
1887

1888
    TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pDag));
10!
1889
  }
1890

1891
_exit:
9✔
1892

1893
  if (code) {
9!
UNCOV
1894
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1895
  }
1896

1897
  nodesDestroyNode((SNode *)pDag);
9✔
1898
  taosArrayDestroy(deployTaskList);
9✔
1899

1900
  return code;
9✔
1901
}
1902

1903

1904
int32_t msmSetStreamRunnerExecReplica(int64_t streamId, SStmStatus* pInfo) {
242✔
1905
  int32_t code = TSDB_CODE_SUCCESS;
242✔
1906
  int32_t lino = 0;
242✔
1907
  //STREAMTODO 
1908
  
1909
  pInfo->runnerDeploys = MND_STREAM_RUNNER_DEPLOY_NUM;
242✔
1910
  pInfo->runnerReplica = 3;
242✔
1911

1912
_exit:
242✔
1913

1914
  if (code) {
242!
UNCOV
1915
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1916
  }
1917

1918
  return code;
242✔
1919
}
1920

1921

1922
static int32_t msmBuildRunnerTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
272✔
1923
  if (NULL == pStream->pCreate->calcPlan) {
272✔
1924
    return TSDB_CODE_SUCCESS;
1✔
1925
  }
1926
  
1927
  int32_t code = TSDB_CODE_SUCCESS;
271✔
1928
  int32_t lino = 0;
271✔
1929
  int64_t streamId = pStream->pCreate->streamId;
271✔
1930
  SQueryPlan* pPlan = NULL;
271✔
1931

1932
  TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pPlan));
271!
1933

1934
  for (int32_t i = 0; i < pInfo->runnerDeploys; ++i) {
1,084✔
1935
    pInfo->runners[i] = taosArrayInit(pPlan->numOfSubplans, sizeof(SStmTaskStatus));
813✔
1936
    TSDB_CHECK_NULL(pInfo->runners[i], code, lino, _exit, terrno);
813!
1937
  }
1938

1939
  code = msmBuildRunnerTasksImpl(pCtx, pPlan, pInfo, pStream);
271✔
1940
  pPlan = NULL;
271✔
1941
  
1942
  TAOS_CHECK_EXIT(code);
271!
1943

1944
  taosHashClear(mStreamMgmt.toUpdateScanMap);
271✔
1945
  mStreamMgmt.toUpdateScanNum = 0;
271✔
1946

1947
_exit:
271✔
1948

1949
  nodesDestroyNode((SNode *)pPlan);
271✔
1950

1951
  if (code) {
271!
UNCOV
1952
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1953
  }
1954

1955
  return code;
271✔
1956
}
1957

1958

1959
static int32_t msmBuildStreamTasks(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
272✔
1960
  int32_t code = TSDB_CODE_SUCCESS;
272✔
1961
  int32_t lino = 0;
272✔
1962
  int64_t streamId = pStream->pCreate->streamId;
272✔
1963

1964
  mstsInfo("start to deploy stream tasks, deployTimes:%" PRId64, pInfo->deployTimes);
272!
1965

1966
  pCtx->triggerTaskId = msmAssignTaskId();
272✔
1967
  pCtx->triggerNodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
272✔
1968
  if (!GOT_SNODE(pCtx->triggerNodeId)) {
272!
UNCOV
1969
    TAOS_CHECK_EXIT(terrno);
×
1970
  }
1971

1972
  TAOS_CHECK_EXIT(msmBuildReaderTasks(pCtx, pInfo, pStream));
272!
1973
  TAOS_CHECK_EXIT(msmBuildRunnerTasks(pCtx, pInfo, pStream));
272!
1974
  TAOS_CHECK_EXIT(msmBuildTriggerTasks(pCtx, pInfo, pStream));
272!
1975
  
1976
_exit:
272✔
1977

1978
  if (code) {
272!
1979
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
1980
  }
1981

1982
  return code;
272✔
1983
}
1984

UNCOV
1985
static int32_t msmInitTrigReaderList(SStmGrpCtx* pCtx, SStmStatus* pInfo, SStreamObj* pStream) {
×
UNCOV
1986
  int32_t code = TSDB_CODE_SUCCESS;
×
1987
  int32_t lino = 0;
×
1988
  int64_t streamId = pStream->pCreate->streamId;
×
1989
  SSdb   *pSdb = pCtx->pMnode->pSdb;
×
1990
  SStmTaskStatus* pState = NULL;
×
UNCOV
1991
  SDbObj* pDb = NULL;
×
1992
  
1993
  switch (pStream->pCreate->triggerTblType) {
×
1994
    case TSDB_NORMAL_TABLE:
×
1995
    case TSDB_CHILD_TABLE:
1996
    case TSDB_VIRTUAL_CHILD_TABLE:
1997
    case TSDB_VIRTUAL_NORMAL_TABLE: {
UNCOV
1998
      pInfo->trigReaders = taosArrayInit_s(sizeof(SStmTaskStatus), 1);
×
UNCOV
1999
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
×
2000
      pInfo->trigReaderNum = 1;
×
2001
      break;
×
2002
    }
2003
    case TSDB_SUPER_TABLE: {
×
2004
      pDb = mndAcquireDb(pCtx->pMnode, pStream->pCreate->triggerDB);
×
2005
      if (NULL == pDb) {
×
UNCOV
2006
        code = terrno;
×
2007
        mstsError("failed to acquire db %s, error:%s", pStream->pCreate->triggerDB, terrstr());
×
2008
        goto _exit;
×
2009
      }
2010

UNCOV
2011
      pInfo->trigReaders = taosArrayInit(pDb->cfg.numOfVgroups, sizeof(SStmTaskStatus));
×
UNCOV
2012
      TSDB_CHECK_NULL(pInfo->trigReaders, code, lino, _exit, terrno);
×
2013
      pInfo->trigReaderNum = pDb->cfg.numOfVgroups;
×
UNCOV
2014
      mndReleaseDb(pCtx->pMnode, pDb);
×
2015
      pDb = NULL;
×
2016
      break;
×
2017
    }
UNCOV
2018
    default:
×
UNCOV
2019
      pInfo->trigReaderNum = 0;
×
2020
      mstsDebug("%s ignore triggerTblType %d", __FUNCTION__, pStream->pCreate->triggerTblType);
×
UNCOV
2021
      break;
×
2022
  }
2023

UNCOV
2024
_exit:
×
2025

UNCOV
2026
  if (code) {
×
UNCOV
2027
    mndReleaseDb(pCtx->pMnode, pDb);
×
UNCOV
2028
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2029
  }
2030

UNCOV
2031
  return code;
×
2032
}
2033

2034

2035
static int32_t msmInitStmStatus(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStreamObj* pStream, bool initList) {
243✔
2036
  int32_t code = TSDB_CODE_SUCCESS;
243✔
2037
  int32_t lino = 0;
243✔
2038
  int64_t streamId = pStream->pCreate->streamId;
243✔
2039

2040
  pStatus->lastActionTs = INT64_MIN;
243✔
2041

2042
  if (NULL == pStatus->streamName) {
243!
2043
    pStatus->streamName = taosStrdup(pStream->name);
243!
2044
    TSDB_CHECK_NULL(pStatus->streamName, code, lino, _exit, terrno);
243!
2045
  }
2046

2047
  TAOS_CHECK_EXIT(tCloneStreamCreateDeployPointers(pStream->pCreate, &pStatus->pCreate));
243!
2048
  
2049
  if (pStream->pCreate->numOfCalcSubplan > 0) {
243✔
2050
    pStatus->runnerNum = pStream->pCreate->numOfCalcSubplan;
242✔
2051
    
2052
    TAOS_CHECK_EXIT(msmSetStreamRunnerExecReplica(streamId, pStatus));
242!
2053
  }
2054

2055
  if (initList) {
243!
2056
    TAOS_CHECK_EXIT(msmInitTrigReaderList(pCtx, pStatus, pStream));
×
2057

UNCOV
2058
    int32_t subPlanNum = taosArrayGetSize(pStream->pCreate->calcScanPlanList);
×
UNCOV
2059
    if (subPlanNum > 0) {
×
UNCOV
2060
      pStatus->calcReaderNum = subPlanNum;
×
UNCOV
2061
      pStatus->calcReaders = taosArrayInit(subPlanNum, sizeof(SStmTaskStatus));
×
UNCOV
2062
      TSDB_CHECK_NULL(pStatus->calcReaders, code, lino, _exit, terrno);
×
2063
    }
2064

2065
    if (pStatus->runnerNum > 0) {
×
UNCOV
2066
      for (int32_t i = 0; i < pStatus->runnerDeploys; ++i) {
×
UNCOV
2067
        pStatus->runners[i] = taosArrayInit(pStatus->runnerNum, sizeof(SStmTaskStatus));
×
UNCOV
2068
        TSDB_CHECK_NULL(pStatus->runners[i], code, lino, _exit, terrno);
×
2069
      }
2070
    }
2071
  }
2072
  
2073
_exit:
243✔
2074

2075
  if (code) {
243!
UNCOV
2076
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2077
  }
2078

2079
  return code;
243✔
2080
}
2081

2082
static int32_t msmDeployStreamTasks(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmStatus* pStatus) {
272✔
2083
  int32_t code = TSDB_CODE_SUCCESS;
272✔
2084
  int32_t lino = 0;
272✔
2085
  int64_t streamId = pStream->pCreate->streamId;
272✔
2086
  SStmStatus info = {0};
272✔
2087

2088
  if (NULL == pStatus) {
272✔
2089
    TAOS_CHECK_EXIT(msmInitStmStatus(pCtx, &info, pStream, false));
243!
2090

2091
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.streamMap, &streamId, sizeof(streamId), &info, sizeof(info)));
243!
2092

2093
    pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
243✔
2094
  }
2095
  
2096
  TAOS_CHECK_EXIT(msmBuildStreamTasks(pCtx, pStatus, pStream));
272!
2097

2098
  mstLogSStmStatus("stream deployed", streamId, pStatus);
272✔
2099

2100
_exit:
272✔
2101

2102
  if (code) {
272!
UNCOV
2103
    if (NULL != pStatus) {
×
UNCOV
2104
      msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
UNCOV
2105
      mstsError("stream build error:%s, will try to stop current stream", tstrerror(code));
×
2106
    }
2107
    
UNCOV
2108
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2109
  }
2110

2111
  return code;
272✔
2112
}
2113

2114

2115
static int32_t msmSTRemoveStream(int64_t streamId, bool fromStreamMap) {
37✔
2116
  int32_t code = TSDB_CODE_SUCCESS;
37✔
2117
  void* pIter = NULL;
37✔
2118

2119
  while ((pIter = taosHashIterate(mStreamMgmt.toDeployVgMap, pIter))) {
61✔
2120
    SStmVgTasksToDeploy* pVg = (SStmVgTasksToDeploy*)pIter;
24✔
2121
    mstWaitLock(&pVg->lock, true);
24✔
2122

2123
    int32_t taskNum = taosArrayGetSize(pVg->taskList);
24✔
2124
    if (atomic_load_32(&pVg->deployed) == taskNum) {
24✔
2125
      taosRUnLockLatch(&pVg->lock);
1✔
2126
      continue;
1✔
2127
    }
2128

2129
    for (int32_t i = 0; i < taskNum; ++i) {
91✔
2130
      SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, i);
68✔
2131
      if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
68✔
2132
        continue;
64✔
2133
      }
2134
      
2135
      pExt->deployed = true;
4✔
2136
    }
2137
    
2138
    taosRUnLockLatch(&pVg->lock);
23✔
2139
  }
2140

2141
  while ((pIter = taosHashIterate(mStreamMgmt.toDeploySnodeMap, pIter))) {
70✔
2142
    SStmSnodeTasksDeploy* pSnode = (SStmSnodeTasksDeploy*)pIter;
33✔
2143
    mstWaitLock(&pSnode->lock, true);
33✔
2144

2145
    int32_t taskNum = taosArrayGetSize(pSnode->triggerList);
33✔
2146
    if (atomic_load_32(&pSnode->triggerDeployed) != taskNum) {
33✔
2147
      for (int32_t i = 0; i < taskNum; ++i) {
55✔
2148
        SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, i);
31✔
2149
        if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
31!
2150
          continue;
31✔
2151
        }
2152
        
UNCOV
2153
        pExt->deployed = true;
×
2154
      }
2155
    }
2156

2157
    taskNum = taosArrayGetSize(pSnode->runnerList);
33✔
2158
    if (atomic_load_32(&pSnode->runnerDeployed) != taskNum) {
33!
2159
      for (int32_t i = 0; i < taskNum; ++i) {
126✔
2160
        SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, i);
93✔
2161
        if (pExt->deployed || pExt->deploy.task.streamId != streamId) {
93!
2162
          continue;
93✔
2163
        }
2164
        
UNCOV
2165
        pExt->deployed = true;
×
2166
      }
2167
    }
2168

2169
    taosRUnLockLatch(&pSnode->lock);
33✔
2170
  }
2171

2172
  
2173
  while ((pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter))) {
162✔
2174
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
125✔
2175
    code = taosHashRemove(pSnode->streamTasks, &streamId, sizeof(streamId));
125✔
2176
    if (TSDB_CODE_SUCCESS == code) {
125✔
2177
      mstsDebug("stream removed from snodeMap %d, remainStreams:%d", *(int32_t*)taosHashGetKey(pIter, NULL), (int32_t)taosHashGetSize(pSnode->streamTasks));
54✔
2178
    }
2179
  }
2180

2181
  while ((pIter = taosHashIterate(mStreamMgmt.vgroupMap, pIter))) {
166✔
2182
    SStmVgroupStatus* pVg = (SStmVgroupStatus*)pIter;
129✔
2183
    code = taosHashRemove(pVg->streamTasks, &streamId, sizeof(streamId));
129✔
2184
    if (TSDB_CODE_SUCCESS == code) {
129✔
2185
      mstsDebug("stream removed from vgroupMap %d, remainStreams:%d", *(int32_t*)taosHashGetKey(pIter, NULL), (int32_t)taosHashGetSize(pVg->streamTasks));
48✔
2186
    }
2187
  }
2188

2189
  size_t keyLen = 0;
37✔
2190
  while ((pIter = taosHashIterate(mStreamMgmt.taskMap, pIter))) {
1,483✔
2191
    int64_t* pStreamId = taosHashGetKey(pIter, &keyLen);
1,446✔
2192
    if (*pStreamId == streamId) {
1,446✔
2193
      int64_t taskId = *(pStreamId + 1);
230✔
2194
      code = taosHashRemove(mStreamMgmt.taskMap, pStreamId, keyLen);
230✔
2195
      if (code) {
230!
UNCOV
2196
        mstsError("TASK:%" PRId64 " remove from taskMap failed, error:%s", taskId, tstrerror(code));
×
2197
      } else {
2198
        mstsDebug("TASK:%" PRId64 " removed from taskMap", taskId);
230✔
2199
      }
2200
    }
2201
  }
2202

2203
  if (fromStreamMap) {
37✔
2204
    code = taosHashRemove(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
8✔
2205
    if (code) {
8!
UNCOV
2206
      mstsError("stream remove from streamMap failed, error:%s", tstrerror(code));
×
2207
    } else {
2208
      mstsDebug("stream removed from streamMap, remains:%d", taosHashGetSize(mStreamMgmt.streamMap));
8✔
2209
    }
2210
  }
2211
  
2212
  return code;
37✔
2213
}
2214

2215
static void msmResetStreamForRedeploy(int64_t streamId, SStmStatus* pStatus) {
29✔
2216
  mstsInfo("try to reset stream for redeploy, stopped:%d, current deployTimes:%" PRId64, atomic_load_8(&pStatus->stopped), pStatus->deployTimes);
29!
2217
  
2218
  msmSTRemoveStream(streamId, false);  
29✔
2219

2220
  mstResetSStmStatus(pStatus);
29✔
2221

2222
  pStatus->deployTimes++;
29✔
2223
}
29✔
2224

2225
static int32_t msmLaunchStreamDeployAction(SStmGrpCtx* pCtx, SStmStreamAction* pAction) {
274✔
2226
  int32_t code = TSDB_CODE_SUCCESS;
274✔
2227
  int32_t lino = 0;
274✔
2228
  int64_t streamId = pAction->streamId;
274✔
2229
  char* streamName = pAction->streamName;
274✔
2230
  SStreamObj* pStream = NULL;
274✔
2231
  int8_t stopped = 0;
274✔
2232

2233
  SStmStatus* pStatus = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
274✔
2234
  if (pStatus) {
274✔
2235
    stopped = atomic_load_8(&pStatus->stopped);
29✔
2236
    if (0 == stopped) {
29!
UNCOV
2237
      mstsDebug("stream %s already running and in streamMap, ignore deploy it", pAction->streamName);
×
UNCOV
2238
      return code;
×
2239
    }
2240

2241
    if (MST_IS_USER_STOPPED(stopped) && !pAction->userAction) {
29!
UNCOV
2242
      mstsWarn("stream %s already stopped by user, stopped:%d, ignore deploy it", pAction->streamName, stopped);
×
2243
      return code;
×
2244
    }
2245
    
2246
    if (stopped == atomic_val_compare_exchange_8(&pStatus->stopped, stopped, 0)) {
29!
2247
      mstsDebug("stream %s will try to reset and redeploy it", pAction->streamName);
29✔
2248
      msmResetStreamForRedeploy(streamId, pStatus);
29✔
2249
    }
2250
  }
2251

2252
  code = mndAcquireStream(pCtx->pMnode, streamName, &pStream);
274✔
2253
  if (TSDB_CODE_MND_STREAM_NOT_EXIST == code) {
274✔
2254
    mstsWarn("stream %s no longer exists, ignore deploy", streamName);
2!
2255
    return TSDB_CODE_SUCCESS;
2✔
2256
  }
2257

2258
  TAOS_CHECK_EXIT(code);
272!
2259

2260
  if (pStatus && pStream->pCreate->streamId != streamId) {
272!
UNCOV
2261
    mstsWarn("stream %s already dropped by user, ignore deploy it", pAction->streamName);
×
UNCOV
2262
    atomic_store_8(&pStatus->stopped, 2);
×
2263
    mstsInfo("set stream %s stopped by user since streamId mismatch", streamName);
×
UNCOV
2264
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_EXIST);
×
2265
  }
2266

2267
  int8_t userStopped = atomic_load_8(&pStream->userStopped);
272✔
2268
  int8_t userDropped = atomic_load_8(&pStream->userDropped);
272✔
2269
  if (userStopped || userDropped) {
272!
UNCOV
2270
    mstsWarn("stream %s is stopped %d or removing %d, ignore deploy", streamName, userStopped, userDropped);
×
UNCOV
2271
    goto _exit;
×
2272
  }
2273
  
2274
  TAOS_CHECK_EXIT(msmDeployStreamTasks(pCtx, pStream, pStatus));
272!
2275

2276
_exit:
272✔
2277

2278
  mndReleaseStream(pCtx->pMnode, pStream);
272✔
2279

2280
  if (code) {
272!
UNCOV
2281
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2282
  }
2283

2284
  return code;
272✔
2285
}
2286

2287
static int32_t msmReLaunchReaderTask(SStreamObj* pStream, SStmTaskAction* pAction, SStmStatus* pStatus) {
28✔
2288
  int32_t code = TSDB_CODE_SUCCESS;
28✔
2289
  int32_t lino = 0;
28✔
2290
  int64_t streamId = pAction->streamId;
28✔
2291
  SStmTaskStatus** ppTask = taosHashGet(mStreamMgmt.taskMap, &pAction->streamId, sizeof(pAction->streamId) + sizeof(pAction->id.taskId));
28✔
2292
  if (NULL == ppTask) {
28!
UNCOV
2293
    mstsError("TASK:%" PRId64 " not in taskMap, remain:%d", pAction->id.taskId, taosHashGetSize(mStreamMgmt.taskMap));
×
2294
    TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
2295
  }
2296
  
2297
  SStmTaskDeploy info = {0};
28✔
2298
  info.task.type = pAction->type;
28✔
2299
  info.task.streamId = pAction->streamId;
28✔
2300
  info.task.taskId = pAction->id.taskId;
28✔
2301
  info.task.seriousId = (*ppTask)->id.seriousId;
28✔
2302
  info.task.nodeId = pAction->id.nodeId;
28✔
2303
  info.task.taskIdx = pAction->id.taskIdx;
28✔
2304
  
2305
  bool isTriggerReader = STREAM_IS_TRIGGER_READER(pAction->flag);
28✔
2306
  SStreamCalcScan* scanPlan = NULL;
28✔
2307
  if (!isTriggerReader) {
28✔
2308
    scanPlan = taosArrayGet(pStatus->pCreate->calcScanPlanList, pAction->id.taskIdx);
14✔
2309
    if (NULL == scanPlan) {
14!
UNCOV
2310
      mstsError("fail to get TASK:%" PRId64 " scanPlan, taskIdx:%d, scanPlanNum:%zu", 
×
2311
          pAction->id.taskId, pAction->id.taskIdx, taosArrayGetSize(pStatus->pCreate->calcScanPlanList));
UNCOV
2312
      TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
2313
    }
2314
  }
2315
  
2316
  TAOS_CHECK_EXIT(msmBuildReaderDeployInfo(&info, scanPlan ? scanPlan->scanPlan : NULL, pStatus, isTriggerReader));
28!
2317
  TAOS_CHECK_EXIT(msmTDAddToVgroupMap(mStreamMgmt.toDeployVgMap, &info, pAction->streamId));
28!
2318

2319
_exit:
28✔
2320

2321
  if (code) {
28!
UNCOV
2322
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2323
  }
2324

2325
  return code;
28✔
2326
}
2327

2328
/*
2329
static int32_t msmReLaunchTriggerTask(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmTaskAction* pAction, SStmStatus* pStatus) {
2330
  int32_t code = TSDB_CODE_SUCCESS;
2331
  int32_t lino = 0;
2332
  int64_t streamId = pAction->streamId;
2333
  SStmTaskStatus** ppTask = taosHashGet(mStreamMgmt.taskMap, &pAction->streamId, sizeof(pAction->streamId) + sizeof(pAction->id.taskId));
2334
  if (NULL == ppTask) {
2335
    mstsError("TASK:%" PRId64 " not in taskMap, remain:%d", pAction->id.taskId, taosHashGetSize(mStreamMgmt.taskMap));
2336
    TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
2337
  }
2338
  
2339
  (*ppTask)->id.nodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
2340
  if (!GOT_SNODE((*ppTask)->id.nodeId)) {
2341
    mstsError("no avaible snode for deploying trigger task, seriousId: %" PRId64, (*ppTask)->id.seriousId);
2342
    return TSDB_CODE_SUCCESS;
2343
  }
2344
  
2345
  SStmTaskDeploy info = {0};
2346
  info.task.type = pAction->type;
2347
  info.task.streamId = streamId;
2348
  info.task.taskId = pAction->id.taskId;
2349
  info.task.seriousId = (*ppTask)->id.seriousId;
2350
  info.task.nodeId = (*ppTask)->id.nodeId;
2351
  info.task.taskIdx = pAction->id.taskIdx;
2352
  
2353
  TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pStatus, &info, pStream));
2354
  TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
2355
  TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, *ppTask, 1, -1));
2356
  
2357
  atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
2358

2359
_exit:
2360

2361
  if (code) {
2362
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
2363
  }
2364

2365
  return code;
2366
}
2367
*/
2368

2369
static int32_t msmReLaunchRunnerDeploy(SStmGrpCtx* pCtx, SStreamObj* pStream, SStmTaskAction* pAction, SStmStatus* pStatus) {
9✔
2370
  int32_t code = TSDB_CODE_SUCCESS;
9✔
2371
  int32_t lino = 0;
9✔
2372
  int64_t streamId = pAction->streamId;
9✔
2373
  
2374
/*
2375
  if (pAction->triggerStatus) {
2376
    pCtx->triggerTaskId = pAction->triggerStatus->id.taskId;
2377
    pAction->triggerStatus->id.nodeId = msmAssignTaskSnodeId(pCtx->pMnode, pStream, true);
2378
    if (!GOT_SNODE(pAction->triggerStatus->id.nodeId)) {
2379
      mstsError("no avaible snode for deploying trigger task, seriousId:%" PRId64, pAction->triggerStatus->id.seriousId);
2380
      return TSDB_CODE_SUCCESS;
2381
    }
2382
  
2383
    pCtx->triggerNodeId = pAction->triggerStatus->id.nodeId;
2384
  } else {
2385
*/
2386
  pCtx->triggerTaskId = pStatus->triggerTask->id.taskId;
9✔
2387
  pCtx->triggerNodeId = pStatus->triggerTask->id.nodeId;
9✔
2388
//  }
2389
  
2390
  TAOS_CHECK_EXIT(msmUPPrepareReaderTasks(pCtx, pStatus, pStream));
9!
2391
  
2392
  SQueryPlan* pPlan = NULL;
9✔
2393
  TAOS_CHECK_EXIT(nodesStringToNode(pStream->pCreate->calcPlan, (SNode**)&pPlan));
9!
2394
  
2395
  TAOS_CHECK_EXIT(msmReBuildRunnerTasks(pCtx, pPlan, pStatus, pStream, pAction));
9!
2396
  
2397
  taosHashClear(mStreamMgmt.toUpdateScanMap);
9✔
2398
  mStreamMgmt.toUpdateScanNum = 0;
9✔
2399
  
2400
/*
2401
  if (pAction->triggerStatus) {
2402
    SStmTaskDeploy info = {0};
2403
    info.task.type = STREAM_TRIGGER_TASK;
2404
    info.task.streamId = streamId;
2405
    info.task.taskId = pCtx->triggerTaskId;
2406
    info.task.seriousId = pAction->triggerStatus->id.seriousId;
2407
    info.task.nodeId = pCtx->triggerNodeId;
2408
    info.task.taskIdx = 0;
2409
  
2410
    TAOS_CHECK_EXIT(msmBuildTriggerDeployInfo(pCtx->pMnode, pStatus, &info, pStream));
2411
    TAOS_CHECK_EXIT(msmTDAddTriggerToSnodeMap(&info, pStream));
2412
    TAOS_CHECK_EXIT(msmSTAddToSnodeMap(pCtx, streamId, NULL, pAction->triggerStatus, 1, -1));
2413
    
2414
    atomic_add_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
2415
  }
2416
*/
2417

2418
_exit:
9✔
2419

2420
  if (code) {
9!
2421
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2422
  }
2423

2424
  return code;
9✔
2425
}
2426

2427

2428
static int32_t msmLaunchTaskDeployAction(SStmGrpCtx* pCtx, SStmTaskAction* pAction) {
37✔
2429
  int32_t code = TSDB_CODE_SUCCESS;
37✔
2430
  int32_t lino = 0;
37✔
2431
  int64_t streamId = pAction->streamId;
37✔
2432
  int64_t taskId = pAction->id.taskId;
37✔
2433
  SStreamObj* pStream = NULL;
37✔
2434

2435
  mstsDebug("start to handle stream tasks action, action task type:%s", gStreamTaskTypeStr[pAction->type]);
37!
2436

2437
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &pAction->streamId, sizeof(pAction->streamId));
37✔
2438
  if (NULL == pStatus) {
37!
UNCOV
2439
    mstsWarn("stream not in streamMap, remain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
UNCOV
2440
    return TSDB_CODE_SUCCESS;
×
2441
  }
2442

2443
  int8_t stopped = atomic_load_8(&pStatus->stopped);
37✔
2444
  if (stopped) {
37!
UNCOV
2445
    mstsWarn("stream %s is already stopped %d, ignore task deploy", pStatus->streamName, stopped);
×
UNCOV
2446
    return TSDB_CODE_SUCCESS;
×
2447
  }
2448

2449
  code = mndAcquireStream(pCtx->pMnode, pStatus->streamName, &pStream);
37✔
2450
  if (TSDB_CODE_MND_STREAM_NOT_EXIST == code) {
37!
UNCOV
2451
    mstsWarn("stream %s no longer exists, ignore task deploy", pStatus->streamName);
×
UNCOV
2452
    return TSDB_CODE_SUCCESS;
×
2453
  }
2454

2455
  TAOS_CHECK_EXIT(code);
37!
2456

2457
  int8_t userStopped = atomic_load_8(&pStream->userStopped);
37✔
2458
  int8_t userDropped = atomic_load_8(&pStream->userDropped);
37✔
2459
  if (userStopped || userDropped) {
37!
2460
    mstsWarn("stream %s is stopped %d or removing %d, ignore task deploy", pStatus->streamName, userStopped, userDropped);
×
UNCOV
2461
    goto _exit;
×
2462
  }
2463

2464
  switch (pAction->type) {
37!
2465
    case STREAM_READER_TASK:
28✔
2466
      TAOS_CHECK_EXIT(msmReLaunchReaderTask(pStream, pAction, pStatus));
28!
2467
      break;
28✔
2468
/*
2469
    case STREAM_TRIGGER_TASK:
2470
      TAOS_CHECK_EXIT(msmReLaunchTriggerTask(pCtx, pStream, pAction, pStatus));
2471
      break;
2472
*/
2473
    case STREAM_RUNNER_TASK:
9✔
2474
      if (pAction->multiRunner) {
9!
2475
        TAOS_CHECK_EXIT(msmReLaunchRunnerDeploy(pCtx, pStream, pAction, pStatus));
9!
2476
      } else {
2477
        mstsError("runner TASK:%" PRId64 " requires relaunch", pAction->id.taskId);
×
UNCOV
2478
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
2479
      }
2480
      break;
9✔
UNCOV
2481
    default:
×
UNCOV
2482
      mstsError("TASK:%" PRId64 " invalid task type:%d", pAction->id.taskId, pAction->type);
×
2483
      TAOS_CHECK_EXIT(TSDB_CODE_STREAM_INTERNAL_ERROR);
×
2484
      break;
×
2485
  }
2486

2487
_exit:
37✔
2488

2489
  if (pStream) {
37!
2490
    mndReleaseStream(pCtx->pMnode, pStream);
37✔
2491
  }
2492

2493
  if (code) {
37!
2494
    msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
2495
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2496
  }
2497

2498
  return code;
37✔
2499
}
2500

UNCOV
2501
static int32_t msmTDRemoveStream(int64_t streamId) {
×
UNCOV
2502
  void* pIter = NULL;
×
2503
  
2504
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
×
2505
    while ((pIter = taosHashIterate(mStreamMgmt.toDeployVgMap, pIter))) {
×
2506
      SStmVgTasksToDeploy* pVg = (SStmVgTasksToDeploy*)pIter;
×
2507
      int32_t taskNum = taosArrayGetSize(pVg->taskList);
×
2508
      if (atomic_load_32(&pVg->deployed) == taskNum) {
×
2509
        continue;
×
2510
      }
2511
      
UNCOV
2512
      for (int32_t i = 0; i < taskNum; ++i) {
×
UNCOV
2513
        SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, i);
×
UNCOV
2514
        if (pExt->deploy.task.streamId == streamId && !pExt->deployed) {
×
UNCOV
2515
          pExt->deployed = true;
×
2516
        }
2517
      }
2518
    }
2519
  }
2520

2521
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0) {
×
UNCOV
2522
    while ((pIter = taosHashIterate(mStreamMgmt.toDeploySnodeMap, pIter))) {
×
UNCOV
2523
      SStmSnodeTasksDeploy* pSnode = (SStmSnodeTasksDeploy*)pIter;
×
UNCOV
2524
      int32_t taskNum = taosArrayGetSize(pSnode->triggerList);
×
UNCOV
2525
      if (atomic_load_32(&pSnode->triggerDeployed) != taskNum) {
×
UNCOV
2526
        for (int32_t i = 0; i < taskNum; ++i) {
×
UNCOV
2527
          SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, i);
×
2528
          if (pExt->deploy.task.streamId == streamId && !pExt->deployed) {
×
UNCOV
2529
            pExt->deployed = true;
×
2530
          }
2531
        }
2532
      }
2533

UNCOV
2534
      taskNum = taosArrayGetSize(pSnode->runnerList);
×
2535
      if (atomic_load_32(&pSnode->runnerDeployed) != taskNum) {
×
UNCOV
2536
        for (int32_t i = 0; i < taskNum; ++i) {
×
2537
          SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, i);
×
UNCOV
2538
          if (pExt->deploy.task.streamId == streamId && !pExt->deployed) {
×
2539
            pExt->deployed = true;
×
2540
          }
2541
        }
2542
      }
2543
    }
2544
  }
2545

UNCOV
2546
  return TSDB_CODE_SUCCESS;
×
2547
}
2548

2549
static int32_t msmRemoveStreamFromMaps(SMnode* pMnode, int64_t streamId) {
8✔
2550
  int32_t code = TSDB_CODE_SUCCESS;
8✔
2551
  int32_t lino = 0;
8✔
2552

2553
  mstsInfo("start to remove stream from maps, current stream num:%d", taosHashGetSize(mStreamMgmt.streamMap));
8!
2554

2555
  TAOS_CHECK_EXIT(msmSTRemoveStream(streamId, true));
8!
2556

2557
_exit:
8✔
2558

2559
  if (code) {
8!
UNCOV
2560
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2561
  } else {
2562
    mstsInfo("end remove stream from maps, current stream num:%d", taosHashGetSize(mStreamMgmt.streamMap));
8!
2563
  }
2564

2565
  return code;
8✔
2566
}
2567

2568
int32_t msmUndeployStream(SMnode* pMnode, int64_t streamId, char* streamName) {
31✔
2569
  int32_t code = TSDB_CODE_SUCCESS;
31✔
2570
  int32_t lino = 0;
31✔
2571

2572
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
31✔
2573
  if (0 == active || MND_STM_STATE_NORMAL != state) {
31!
UNCOV
2574
    mstsError("stream mgmt not available since active:%d state:%d", active, state);
×
2575
    return TSDB_CODE_MND_STREAM_NOT_AVAILABLE;
×
2576
  }
2577

2578
  SStmStatus* pStream = (SStmStatus*)taosHashAcquire(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
31✔
2579
  if (NULL == pStream) {
31✔
2580
    mstsInfo("stream %s already not in streamMap", streamName);
2!
2581
    goto _exit;
2✔
2582
  }
2583

2584
  atomic_store_8(&pStream->stopped, 2);
29✔
2585

2586
  mstsInfo("set stream %s stopped by user", streamName);
29!
2587

2588
_exit:
×
2589

2590
  taosHashRelease(mStreamMgmt.streamMap, pStream);
31✔
2591

2592
  if (code) {
31!
2593
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2594
  }
2595

2596
  return code;
31✔
2597
}
2598

2599
int32_t msmRecalcStream(SMnode* pMnode, int64_t streamId, STimeWindow* timeRange) {
1✔
2600
  int32_t code = TSDB_CODE_SUCCESS;
1✔
2601
  int32_t lino = 0;
1✔
2602

2603
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
1✔
2604
  if (0 == active || MND_STM_STATE_NORMAL != state) {
1!
2605
    mstsError("stream mgmt not available since active:%d state:%d", active, state);
×
UNCOV
2606
    return TSDB_CODE_MND_STREAM_NOT_AVAILABLE;
×
2607
  }
2608

2609
  SStmStatus* pStream = (SStmStatus*)taosHashAcquire(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
1✔
2610
  if (NULL == pStream || !STREAM_IS_RUNNING(pStream)) {
1!
UNCOV
2611
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
UNCOV
2612
    mstsInfo("stream still not in streamMap, streamRemains:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
UNCOV
2613
    goto _exit;
×
2614
  }
2615

2616
  TAOS_CHECK_EXIT(mstAppendNewRecalcRange(streamId, pStream, timeRange));
1!
2617

2618
_exit:
1✔
2619

2620
  taosHashRelease(mStreamMgmt.streamMap, pStream);
1✔
2621

2622
  if (code) {
1!
UNCOV
2623
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2624
  }
2625

2626
  return code;
1✔
2627
}
2628

2629
static int32_t msmHandleStreamActions(SStmGrpCtx* pCtx) {
72✔
2630
  int32_t code = TSDB_CODE_SUCCESS;
72✔
2631
  int32_t lino = 0;
72✔
2632
  SStmQNode* pQNode = NULL;
72✔
2633

2634
  while (mndStreamActionDequeue(mStreamMgmt.actionQ, &pQNode)) {
383✔
2635
    switch (pQNode->type) {
311!
2636
      case STREAM_ACT_DEPLOY:
311✔
2637
        if (pQNode->streamAct) {
311✔
2638
          mstDebug("start to handle stream deploy action");
274✔
2639
          msmLaunchStreamDeployAction(pCtx, &pQNode->action.stream);
274✔
2640
        } else {
2641
          mstDebug("start to handle task deploy action");
37!
2642
          msmLaunchTaskDeployAction(pCtx, &pQNode->action.task);
37✔
2643
        }
2644
        break;
311✔
UNCOV
2645
      default:
×
UNCOV
2646
        break;
×
2647
    }
2648
  }
2649

2650
_exit:
72✔
2651

2652
  if (code) {
72!
UNCOV
2653
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2654
  }
2655

2656
  return code;
72✔
2657
}
2658

UNCOV
2659
void msmStopAllStreamsByGrant(int32_t errCode) {
×
UNCOV
2660
  SStmStatus* pStatus = NULL;
×
UNCOV
2661
  void* pIter = NULL;
×
UNCOV
2662
  int64_t streamId = 0;
×
2663
  
2664
  while (true) {
UNCOV
2665
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
×
UNCOV
2666
    if (NULL == pIter) {
×
UNCOV
2667
      break;
×
2668
    }
2669

UNCOV
2670
    pStatus = (SStmStatus*)pIter;
×
2671

UNCOV
2672
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
UNCOV
2673
    atomic_store_8(&pStatus->stopped, 4);
×
2674

2675
    mstsInfo("set stream stopped since %s", tstrerror(errCode));
×
2676
  }
UNCOV
2677
}
×
2678

UNCOV
2679
int32_t msmHandleGrantExpired(SMnode *pMnode, int32_t errCode) {
×
UNCOV
2680
  mstInfo("stream grant expired");
×
2681

2682
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
×
UNCOV
2683
    mstWarn("mnode stream is NOT active, ignore handling");
×
UNCOV
2684
    return errCode;
×
2685
  }
2686

UNCOV
2687
  mstWaitLock(&mStreamMgmt.runtimeLock, true);
×
2688

UNCOV
2689
  msmStopAllStreamsByGrant(errCode);
×
2690

UNCOV
2691
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
×
2692
  
UNCOV
2693
  return errCode;
×
2694
}
2695

2696
static int32_t msmInitStreamDeploy(SStmStreamDeploy* pStream, SStmTaskDeploy* pDeploy) {
1,589✔
2697
  int32_t code = TSDB_CODE_SUCCESS;
1,589✔
2698
  int32_t lino = 0;
1,589✔
2699
  int64_t streamId = pDeploy->task.streamId;
1,589✔
2700
  
2701
  switch (pDeploy->task.type) {
1,589!
2702
    case STREAM_READER_TASK:
494✔
2703
      if (NULL == pStream->readerTasks) {
494✔
2704
        pStream->streamId = streamId;
320✔
2705
        pStream->readerTasks = taosArrayInit(20, sizeof(SStmTaskDeploy));
320✔
2706
        TSDB_CHECK_NULL(pStream->readerTasks, code, lino, _exit, terrno);
320!
2707
      }
2708
      
2709
      TSDB_CHECK_NULL(taosArrayPush(pStream->readerTasks, pDeploy), code, lino, _exit, terrno);
988!
2710
      break;
494✔
2711
    case STREAM_TRIGGER_TASK:
272✔
2712
      pStream->streamId = streamId;
272✔
2713
      pStream->triggerTask = taosMemoryMalloc(sizeof(SStmTaskDeploy));
272!
2714
      TSDB_CHECK_NULL(pStream->triggerTask, code, lino, _exit, terrno);
272!
2715
      memcpy(pStream->triggerTask, pDeploy, sizeof(SStmTaskDeploy));
272✔
2716
      break;
272✔
2717
    case STREAM_RUNNER_TASK:
823✔
2718
      if (NULL == pStream->runnerTasks) {
823✔
2719
        pStream->streamId = streamId;
311✔
2720
        pStream->runnerTasks = taosArrayInit(20, sizeof(SStmTaskDeploy));
311✔
2721
        TSDB_CHECK_NULL(pStream->runnerTasks, code, lino, _exit, terrno);
311!
2722
      }      
2723
      TSDB_CHECK_NULL(taosArrayPush(pStream->runnerTasks, pDeploy), code, lino, _exit, terrno);
1,646!
2724
      break;
823✔
UNCOV
2725
    default:
×
UNCOV
2726
      break;
×
2727
  }
2728

2729
_exit:
1,589✔
2730

2731
  if (code) {
1,589!
UNCOV
2732
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2733
  }
2734

2735
  return code;
1,589✔
2736
}
2737

2738
static int32_t msmGrpAddDeployTask(SHashObj* pHash, SStmTaskDeploy* pDeploy) {
1,589✔
2739
  int32_t code = TSDB_CODE_SUCCESS;
1,589✔
2740
  int32_t lino = 0;
1,589✔
2741
  int64_t streamId = pDeploy->task.streamId;
1,589✔
2742
  SStreamTask* pTask = &pDeploy->task;
1,589✔
2743
  SStmStreamDeploy streamDeploy = {0};
1,589✔
2744
  SStmStreamDeploy* pStream = NULL;
1,589✔
2745
   
2746
  while (true) {
2747
    pStream = taosHashAcquire(pHash, &streamId, sizeof(streamId));
1,589✔
2748
    if (NULL == pStream) {
1,589✔
2749
      TAOS_CHECK_EXIT(msmInitStreamDeploy(&streamDeploy, pDeploy));
383!
2750
      code = taosHashPut(pHash, &streamId, sizeof(streamId), &streamDeploy, sizeof(streamDeploy));
383✔
2751
      if (TSDB_CODE_SUCCESS == code) {
383!
2752
        goto _exit;
383✔
2753
      }
2754

UNCOV
2755
      if (TSDB_CODE_DUP_KEY != code) {
×
UNCOV
2756
        goto _exit;
×
2757
      }    
2758

UNCOV
2759
      tFreeSStmStreamDeploy(&streamDeploy);
×
UNCOV
2760
      continue;
×
2761
    }
2762

2763
    TAOS_CHECK_EXIT(msmInitStreamDeploy(pStream, pDeploy));
1,206!
2764
    
2765
    break;
1,206✔
2766
  }
2767
  
2768
_exit:
1,589✔
2769

2770
  taosHashRelease(pHash, pStream);
1,589✔
2771

2772
  if (code) {
1,589!
UNCOV
2773
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2774
  } else {
2775
    msttDebug("task added to GRP deployMap, taskIdx:%d", pTask->taskIdx);
1,589✔
2776
  }
2777

2778
  return code;
1,589✔
2779
}
2780

2781

2782
int32_t msmGrpAddDeployTasks(SHashObj* pHash, SArray* pTasks, int32_t* deployed) {
305✔
2783
  int32_t code = TSDB_CODE_SUCCESS;
305✔
2784
  int32_t lino = 0;
305✔
2785
  int32_t taskNum = taosArrayGetSize(pTasks);
305✔
2786

2787
  for (int32_t i = 0; i < taskNum; ++i) {
1,898✔
2788
    SStmTaskToDeployExt* pExt = taosArrayGet(pTasks, i);
1,593✔
2789
    if (pExt->deployed) {
1,593✔
2790
      continue;
4✔
2791
    }
2792

2793
    TAOS_CHECK_EXIT(msmGrpAddDeployTask(pHash, &pExt->deploy));
1,589!
2794
    pExt->deployed = true;
1,589✔
2795

2796
    atomic_add_fetch_32(deployed, 1);
1,589✔
2797
  }
2798

2799
_exit:
305✔
2800

2801
  if (code) {
305!
UNCOV
2802
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2803
  }
2804

2805
  return code;
305✔
2806
}
2807

2808
int32_t msmGrpAddDeployVgTasks(SStmGrpCtx* pCtx) {
159✔
2809
  int32_t code = TSDB_CODE_SUCCESS;
159✔
2810
  int32_t lino = 0;
159✔
2811
  int32_t vgNum = taosArrayGetSize(pCtx->pReq->pVgLeaders);
159✔
2812
  SStmVgTasksToDeploy* pVg = NULL;
159✔
2813
  //int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pCtx->pReq->streamGId);
2814

2815
  mstDebug("start to add stream vgroup tasks deploy");
159✔
2816
  
2817
  for (int32_t i = 0; i < vgNum; ++i) {
535✔
2818
    int32_t* vgId = taosArrayGet(pCtx->pReq->pVgLeaders, i);
376✔
2819

2820
    msmUpdateVgroupUpTs(pCtx, *vgId);
376✔
2821

2822
    pVg = taosHashAcquire(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId));
376✔
2823
    if (NULL == pVg) {
376✔
2824
      continue;
223✔
2825
    }
2826

2827
    if (taosRTryLockLatch(&pVg->lock)) {
153!
UNCOV
2828
      continue;
×
2829
    }
2830
    
2831
    if (atomic_load_32(&pVg->deployed) == taosArrayGetSize(pVg->taskList)) {
153!
2832
      taosRUnLockLatch(&pVg->lock);
×
UNCOV
2833
      continue;
×
2834
    }
2835
    
2836
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pVg->taskList, &pVg->deployed));
153!
2837
    taosRUnLockLatch(&pVg->lock);
153✔
2838
  }
2839

2840
_exit:
159✔
2841

2842
  if (code) {
159!
UNCOV
2843
    if (pVg) {
×
UNCOV
2844
      taosRUnLockLatch(&pVg->lock);
×
2845
    }
2846

2847
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2848
  }
2849

2850
  return code;
159✔
2851
}
2852

2853
int32_t msmGrpAddDeploySnodeTasks(SStmGrpCtx* pCtx) {
109✔
2854
  int32_t code = TSDB_CODE_SUCCESS;
109✔
2855
  int32_t lino = 0;
109✔
2856
  SStmSnodeTasksDeploy* pSnode = NULL;
109✔
2857
  SStreamHbMsg* pReq = pCtx->pReq;
109✔
2858

2859
  mstDebug("start to add stream snode tasks deploy");
109✔
2860
  
2861
  pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &pReq->snodeId, sizeof(pReq->snodeId));
109✔
2862
  if (NULL == pSnode) {
109✔
2863
    return TSDB_CODE_SUCCESS;
28✔
2864
  }
2865

2866
  mstWaitLock(&pSnode->lock, false);
81✔
2867
  
2868
  if (atomic_load_32(&pSnode->triggerDeployed) < taosArrayGetSize(pSnode->triggerList)) {
81✔
2869
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pSnode->triggerList, &pSnode->triggerDeployed));
71!
2870
  }
2871

2872
  if (atomic_load_32(&pSnode->runnerDeployed) < taosArrayGetSize(pSnode->runnerList)) {
81!
2873
    TAOS_CHECK_EXIT(msmGrpAddDeployTasks(pCtx->deployStm, pSnode->runnerList, &pSnode->runnerDeployed));
81!
2874
  }
2875
  
2876
  taosWUnLockLatch(&pSnode->lock);
81✔
2877

2878
_exit:
81✔
2879

2880
  if (code) {
81!
UNCOV
2881
    if (pSnode) {
×
UNCOV
2882
      taosWUnLockLatch(&pSnode->lock);
×
2883
    }
2884

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

2888
  return code;
81✔
2889
}
2890

2891
int32_t msmUpdateStreamLastActTs(int64_t streamId, int64_t currTs) {
933✔
2892
  int32_t code = TSDB_CODE_SUCCESS;
933✔
2893
  int32_t lino = 0;
933✔
2894
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
933✔
2895
  if (NULL == pStatus) {
933!
UNCOV
2896
    mstsWarn("stream already not exists in streamMap, mapSize:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
2897
    return TSDB_CODE_SUCCESS;
×
2898
  }
2899
  
2900
  pStatus->lastActionTs = currTs;
933✔
2901

2902
_exit:
933✔
2903

2904
  if (code) {
933!
UNCOV
2905
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2906
  }
2907

2908
  return code;
933✔
2909
}
2910

2911
int32_t msmRspAddStreamsDeploy(SStmGrpCtx* pCtx) {
104✔
2912
  int32_t code = TSDB_CODE_SUCCESS;
104✔
2913
  int32_t lino = 0;
104✔
2914
  int32_t streamNum = taosHashGetSize(pCtx->deployStm);
104✔
2915
  void* pIter = NULL;
104✔
2916

2917
  mstDebug("start to add group %d deploy streams, streamNum:%d", pCtx->pReq->streamGId, taosHashGetSize(pCtx->deployStm));
104✔
2918
  
2919
  pCtx->pRsp->deploy.streamList = taosArrayInit(streamNum, sizeof(SStmStreamDeploy));
104✔
2920
  TSDB_CHECK_NULL(pCtx->pRsp->deploy.streamList, code, lino, _exit, terrno);
104!
2921

2922
  while (1) {
383✔
2923
    pIter = taosHashIterate(pCtx->deployStm, pIter);
487✔
2924
    if (pIter == NULL) {
487✔
2925
      break;
104✔
2926
    }
2927
    
2928
    SStmStreamDeploy *pDeploy = (SStmStreamDeploy *)pIter;
383✔
2929
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->deploy.streamList, pDeploy), code, lino, _exit, terrno);
766!
2930

2931
    int64_t streamId = pDeploy->streamId;
383✔
2932
    mstsDebug("stream DEPLOY added to dnode %d hb rsp, readerTasks:%zu, triggerTask:%d, runnerTasks:%zu", 
383✔
2933
        pCtx->pReq->dnodeId, taosArrayGetSize(pDeploy->readerTasks), pDeploy->triggerTask ? 1 : 0, taosArrayGetSize(pDeploy->runnerTasks));
2934

2935
    mstClearSStmStreamDeploy(pDeploy);
383✔
2936
    
2937
    TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(pDeploy->streamId, pCtx->currTs));
383!
2938
  }
2939
  
2940
_exit:
104✔
2941

2942
  if (pIter) {
104!
UNCOV
2943
    taosHashCancelIterate(pCtx->deployStm, pIter);
×
2944
  }
2945

2946
  if (code) {
104!
2947
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
2948
  }
2949
  
2950
  return code;
104✔
2951
}
2952

2953
void msmCleanDeployedVgTasks(SArray* pVgLeaders) {
159✔
2954
  int32_t code = TSDB_CODE_SUCCESS;
159✔
2955
  int32_t lino = 0;
159✔
2956
  int32_t vgNum = taosArrayGetSize(pVgLeaders);
159✔
2957
  SStmVgTasksToDeploy* pVg = NULL;
159✔
2958
  
2959
  for (int32_t i = 0; i < vgNum; ++i) {
535✔
2960
    int32_t* vgId = taosArrayGet(pVgLeaders, i);
376✔
2961
    pVg = taosHashAcquire(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId));
376✔
2962
    if (NULL == pVg) {
376✔
2963
      continue;
223✔
2964
    }
2965

2966
    if (taosWTryLockLatch(&pVg->lock)) {
153!
UNCOV
2967
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
×
UNCOV
2968
      continue;
×
2969
    }
2970
    
2971
    if (atomic_load_32(&pVg->deployed) <= 0) {
153!
UNCOV
2972
      taosWUnLockLatch(&pVg->lock);
×
UNCOV
2973
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
×
UNCOV
2974
      continue;
×
2975
    }
2976

2977
    int32_t taskNum = taosArrayGetSize(pVg->taskList);
153✔
2978
    if (atomic_load_32(&pVg->deployed) == taskNum) {
153✔
2979
      atomic_sub_fetch_32(&mStreamMgmt.toDeployVgTaskNum, taskNum);
152✔
2980
      taosArrayDestroyEx(pVg->taskList, mstDestroySStmTaskToDeployExt);
152✔
2981
      pVg->taskList = NULL;
152✔
2982
      taosHashRemove(mStreamMgmt.toDeployVgMap, vgId, sizeof(*vgId));
152✔
2983
      taosWUnLockLatch(&pVg->lock);
152✔
2984
      taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
152✔
2985
      continue;
152✔
2986
    }
2987

2988
    for (int32_t m = taskNum - 1; m >= 0; --m) {
11✔
2989
      SStmTaskToDeployExt* pExt = taosArrayGet(pVg->taskList, m);
10✔
2990
      if (!pExt->deployed) {
10!
UNCOV
2991
        continue;
×
2992
      }
2993

2994
      mstDestroySStmTaskToDeployExt(pExt);
10✔
2995

2996
      taosArrayRemove(pVg->taskList, m);
10✔
2997
      atomic_sub_fetch_32(&mStreamMgmt.toDeployVgTaskNum, 1);
10✔
2998
    }
2999
    atomic_store_32(&pVg->deployed, 0);
1✔
3000
    taosWUnLockLatch(&pVg->lock);
1✔
3001
    taosHashRelease(mStreamMgmt.toDeployVgMap, pVg);
1✔
3002
  }
3003

3004
_exit:
159✔
3005

3006
  if (code) {
159!
UNCOV
3007
    if (pVg) {
×
UNCOV
3008
      taosWUnLockLatch(&pVg->lock);
×
3009
    }
3010

3011
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3012
  }
3013
}
159✔
3014

3015
void msmCleanDeployedSnodeTasks (int32_t snodeId) {
123✔
3016
  if (!GOT_SNODE(snodeId)) {
123✔
3017
    return;
14✔
3018
  }
3019
  
3020
  int32_t code = TSDB_CODE_SUCCESS;
109✔
3021
  SStmSnodeTasksDeploy* pSnode = taosHashAcquire(mStreamMgmt.toDeploySnodeMap, &snodeId, sizeof(snodeId));
109✔
3022
  if (NULL == pSnode) {
109✔
3023
    return;
28✔
3024
  }
3025

3026
  if (taosWTryLockLatch(&pSnode->lock)) {
81!
3027
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
×
3028
    return;
×
3029
  }
3030

3031
  int32_t triggerNum = taosArrayGetSize(pSnode->triggerList);
81✔
3032
  int32_t runnerNum = taosArrayGetSize(pSnode->runnerList);
81✔
3033
  
3034
  if (atomic_load_32(&pSnode->triggerDeployed) <= 0 && atomic_load_32(&pSnode->runnerDeployed) <= 0) {
81!
UNCOV
3035
    taosWUnLockLatch(&pSnode->lock);
×
3036
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
×
UNCOV
3037
    return;
×
3038
  }
3039

3040
  if (atomic_load_32(&pSnode->triggerDeployed) == triggerNum) {
81!
3041
    atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, triggerNum);
81✔
3042
    taosArrayDestroyEx(pSnode->triggerList, mstDestroySStmTaskToDeployExt);
81✔
3043
    pSnode->triggerList = NULL;
81✔
3044
  }
3045

3046
  if (atomic_load_32(&pSnode->runnerDeployed) == runnerNum) {
81!
3047
    atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, runnerNum);
81✔
3048
    taosArrayDestroyEx(pSnode->runnerList, mstDestroySStmTaskToDeployExt);
81✔
3049
    pSnode->runnerList = NULL;
81✔
3050
  }
3051

3052
  if (NULL == pSnode->triggerList && NULL == pSnode->runnerList) {
81!
3053
    taosHashRemove(mStreamMgmt.toDeploySnodeMap, &snodeId, sizeof(snodeId));
81✔
3054
    taosWUnLockLatch(&pSnode->lock);
81✔
3055
    taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
81✔
3056
    return;
81✔
3057
  }
3058

3059
  if (atomic_load_32(&pSnode->triggerDeployed) > 0 && pSnode->triggerList) {
×
UNCOV
3060
    for (int32_t m = triggerNum - 1; m >= 0; --m) {
×
UNCOV
3061
      SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->triggerList, m);
×
UNCOV
3062
      if (!pExt->deployed) {
×
UNCOV
3063
        continue;
×
3064
      }
3065

UNCOV
3066
      mstDestroySStmTaskToDeployExt(pExt);
×
UNCOV
3067
      atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
×
UNCOV
3068
      taosArrayRemove(pSnode->triggerList, m);
×
3069
    }
3070
    
UNCOV
3071
    pSnode->triggerDeployed = 0;
×
3072
  }
3073

3074
  if (atomic_load_32(&pSnode->runnerDeployed) > 0 && pSnode->runnerList) {
×
3075
    for (int32_t m = runnerNum - 1; m >= 0; --m) {
×
UNCOV
3076
      SStmTaskToDeployExt* pExt = taosArrayGet(pSnode->runnerList, m);
×
UNCOV
3077
      if (!pExt->deployed) {
×
UNCOV
3078
        continue;
×
3079
      }
3080

UNCOV
3081
      mstDestroySStmTaskToDeployExt(pExt);
×
UNCOV
3082
      atomic_sub_fetch_32(&mStreamMgmt.toDeploySnodeTaskNum, 1);
×
UNCOV
3083
      taosArrayRemove(pSnode->runnerList, m);
×
3084
    }
3085
    
UNCOV
3086
    pSnode->runnerDeployed = 0;
×
3087
  }
3088
  
UNCOV
3089
  taosWUnLockLatch(&pSnode->lock);
×
UNCOV
3090
  taosHashRelease(mStreamMgmt.toDeploySnodeMap, pSnode);
×
3091
}
3092

3093
void msmClearStreamToDeployMaps(SStreamHbMsg* pHb) {
44,293✔
3094
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
44,293!
3095
    return;
×
3096
  }
3097

3098
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
44,293✔
3099
    msmCleanDeployedVgTasks(pHb->pVgLeaders);
159✔
3100
  }
3101

3102
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0) {
44,293✔
3103
    msmCleanDeployedSnodeTasks(pHb->snodeId);
123✔
3104
  }
3105
}
3106

3107
void msmCleanStreamGrpCtx(SStreamHbMsg* pHb) {
44,293✔
3108
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
44,293!
3109
    return;
×
3110
  }
3111

3112
  int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pHb->streamGId);
44,293✔
3113
  taosHashClear(mStreamMgmt.tCtx[tidx].actionStm[pHb->streamGId]);
44,293✔
3114
  taosHashClear(mStreamMgmt.tCtx[tidx].deployStm[pHb->streamGId]);
44,293✔
3115
}
3116

3117
int32_t msmGrpAddActionStart(SHashObj* pHash, int64_t streamId, SStmTaskId* pId) {
340✔
3118
  int32_t code = TSDB_CODE_SUCCESS;
340✔
3119
  int32_t lino = 0;
340✔
3120
  int32_t action = STREAM_ACT_START;
340✔
3121
  SStmAction *pAction = taosHashGet(pHash, &streamId, sizeof(streamId));
340✔
3122
  if (pAction) {
340!
UNCOV
3123
    pAction->actions |= action;
×
UNCOV
3124
    pAction->start.triggerId = *pId;
×
UNCOV
3125
    mstsDebug("stream append START action, actions:%x", pAction->actions);
×
3126
  } else {
3127
    SStmAction newAction = {0};
340✔
3128
    newAction.actions = action;
340✔
3129
    newAction.start.triggerId = *pId;
340✔
3130
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
340!
3131
    mstsDebug("stream add START action, actions:%x", newAction.actions);
340✔
3132
  }
3133

3134
_exit:
340✔
3135

3136
  if (code) {
340!
UNCOV
3137
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3138
  }
3139

3140
  return code;
340✔
3141
}
3142

UNCOV
3143
int32_t msmGrpAddActionUpdateTrigger(SHashObj* pHash, int64_t streamId) {
×
UNCOV
3144
  int32_t code = TSDB_CODE_SUCCESS;
×
UNCOV
3145
  int32_t lino = 0;
×
UNCOV
3146
  int32_t action = STREAM_ACT_UPDATE_TRIGGER;
×
3147
  
UNCOV
3148
  SStmAction *pAction = taosHashGet(pHash, &streamId, sizeof(streamId));
×
UNCOV
3149
  if (pAction) {
×
UNCOV
3150
    pAction->actions |= action;
×
UNCOV
3151
    mstsDebug("stream append UPDATE_TRIGGER action, actions:%x", pAction->actions);
×
3152
  } else {
UNCOV
3153
    SStmAction newAction = {0};
×
UNCOV
3154
    newAction.actions = action;
×
UNCOV
3155
    TAOS_CHECK_EXIT(taosHashPut(pHash, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
×
UNCOV
3156
    mstsDebug("stream add UPDATE_TRIGGER action, actions:%x", newAction.actions);
×
3157
  }
3158

UNCOV
3159
_exit:
×
3160

UNCOV
3161
  if (code) {
×
3162
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3163
  }
3164

UNCOV
3165
  return code;
×
3166
}
3167

3168

3169

3170
int32_t msmGrpAddActionUndeploy(SStmGrpCtx* pCtx, int64_t streamId, SStreamTask* pTask) {
210✔
3171
  int32_t code = TSDB_CODE_SUCCESS;
210✔
3172
  int32_t lino = 0;
210✔
3173
  int32_t action = STREAM_ACT_UNDEPLOY;
210✔
3174
  bool    dropped = false;
210✔
3175

3176
  TAOS_CHECK_EXIT(mstIsStreamDropped(pCtx->pMnode, streamId, &dropped));
210!
3177
  mstsDebug("stream dropped: %d", dropped);
210✔
3178
  
3179
  SStmAction *pAction = taosHashGet(pCtx->actionStm, &streamId, sizeof(streamId));
210✔
3180
  if (pAction) {
210✔
3181
    pAction->actions |= action;
126✔
3182
    if (NULL == pAction->undeploy.taskList) {
126!
UNCOV
3183
      pAction->undeploy.taskList = taosArrayInit(pCtx->taskNum, POINTER_BYTES);
×
3184
      TSDB_CHECK_NULL(pAction->undeploy.taskList, code, lino, _exit, terrno);
×
3185
    }
3186

3187
    TSDB_CHECK_NULL(taosArrayPush(pAction->undeploy.taskList, &pTask), code, lino, _exit, terrno);
252!
3188
    if (pAction->undeploy.doCheckpoint) {
126✔
3189
      pAction->undeploy.doCheckpoint = dropped ? false : true;
92✔
3190
    }
3191
    if (!pAction->undeploy.doCleanup) {
126✔
3192
      pAction->undeploy.doCleanup = dropped ? true : false;
92✔
3193
    }
3194
    
3195
    msttDebug("task append UNDEPLOY action[%d,%d], actions:%x", pAction->undeploy.doCheckpoint, pAction->undeploy.doCleanup, pAction->actions);
126✔
3196
  } else {
3197
    SStmAction newAction = {0};
84✔
3198
    newAction.actions = action;
84✔
3199
    newAction.undeploy.doCheckpoint = dropped ? false : true;
84✔
3200
    newAction.undeploy.doCleanup = dropped ? true : false;
84✔
3201
    newAction.undeploy.taskList = taosArrayInit(pCtx->taskNum, POINTER_BYTES);
84✔
3202
    TSDB_CHECK_NULL(newAction.undeploy.taskList, code, lino, _exit, terrno);
84!
3203
    TSDB_CHECK_NULL(taosArrayPush(newAction.undeploy.taskList, &pTask), code, lino, _exit, terrno);
168!
3204
    TAOS_CHECK_EXIT(taosHashPut(pCtx->actionStm, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
84!
3205
    
3206
    msttDebug("task add UNDEPLOY action[%d,%d]", newAction.undeploy.doCheckpoint, newAction.undeploy.doCleanup);
84✔
3207
  }
3208

3209
_exit:
210✔
3210

3211
  if (code) {
210!
3212
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3213
  }
3214

3215
  return code;
210✔
3216
}
3217

3218
int32_t msmGrpAddActionRecalc(SStmGrpCtx* pCtx, int64_t streamId, SArray* recalcList) {
×
3219
  int32_t code = TSDB_CODE_SUCCESS;
×
3220
  int32_t lino = 0;
×
UNCOV
3221
  int32_t action = STREAM_ACT_RECALC;
×
UNCOV
3222
  SStmAction newAction = {0};
×
3223
  
UNCOV
3224
  SStmAction *pAction = taosHashGet(pCtx->actionStm, &streamId, sizeof(streamId));
×
UNCOV
3225
  if (pAction) {
×
UNCOV
3226
    pAction->actions |= action;
×
UNCOV
3227
    pAction->recalc.recalcList = recalcList;
×
3228

UNCOV
3229
    mstsDebug("stream append recalc action, listSize:%d, actions:%x", (int32_t)taosArrayGetSize(recalcList), pAction->actions);
×
3230
  } else {
UNCOV
3231
    newAction.actions = action;
×
UNCOV
3232
    newAction.recalc.recalcList = recalcList;
×
3233
    
UNCOV
3234
    TAOS_CHECK_EXIT(taosHashPut(pCtx->actionStm, &streamId, sizeof(streamId), &newAction, sizeof(newAction)));
×
3235
    
UNCOV
3236
    mstsDebug("stream add recalc action, listSize:%d", (int32_t)taosArrayGetSize(recalcList));
×
3237
  }
3238

UNCOV
3239
_exit:
×
3240

UNCOV
3241
  if (code) {
×
UNCOV
3242
    mstDestroySStmAction(&newAction);
×
UNCOV
3243
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3244
  }
3245

UNCOV
3246
  return code;
×
3247
}
3248

3249
bool msmCheckStreamStartCond(int64_t streamId, int32_t snodeId) {
379✔
3250
  SStmStatus* pStream = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
379✔
3251
  if (NULL == pStream) {
379!
UNCOV
3252
    return false;
×
3253
  }
3254

3255
  if (pStream->triggerTask->id.nodeId != snodeId || STREAM_STATUS_INIT != pStream->triggerTask->status) {
379!
UNCOV
3256
    return false;
×
3257
  }
3258

3259
  int32_t readerNum = taosArrayGetSize(pStream->trigReaders);
379✔
3260
  for (int32_t i = 0; i < readerNum; ++i) {
768✔
3261
    SStmTaskStatus* pStatus = taosArrayGet(pStream->trigReaders, i);
390✔
3262
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
390✔
3263
      return false;
1✔
3264
    }
3265
  }
3266

3267
  readerNum = taosArrayGetSize(pStream->trigOReaders);
378✔
3268
  for (int32_t i = 0; i < readerNum; ++i) {
415✔
3269
    SStmTaskStatus* pStatus = taosArrayGet(pStream->trigOReaders, i);
37✔
3270
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
37!
UNCOV
3271
      return false;
×
3272
    }
3273
  }
3274

3275
  readerNum = taosArrayGetSize(pStream->calcReaders);
378✔
3276
  for (int32_t i = 0; i < readerNum; ++i) {
590✔
3277
    SStmTaskStatus* pStatus = taosArrayGet(pStream->calcReaders, i);
212✔
3278
    if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
212!
UNCOV
3279
      return false;
×
3280
    }
3281
  }
3282

3283
  for (int32_t i = 0; i < pStream->runnerDeploys; ++i) {
1,395✔
3284
    int32_t runnerNum = taosArrayGetSize(pStream->runners[i]);
1,055✔
3285
    for (int32_t m = 0; m < runnerNum; ++m) {
2,072✔
3286
      SStmTaskStatus* pStatus = taosArrayGet(pStream->runners[i], m);
1,055✔
3287
      if (STREAM_STATUS_INIT != pStatus->status && STREAM_STATUS_RUNNING != pStatus->status) {
1,055!
3288
        return false;
38✔
3289
      }
3290
    }
3291
  }
3292
  
3293
  return true;
340✔
3294
}
3295

3296

3297
void msmHandleTaskAbnormalStatus(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pMsg, SStmTaskStatus* pTaskStatus) {
7,837✔
3298
  int32_t code = TSDB_CODE_SUCCESS;
7,837✔
3299
  int32_t lino = 0;
7,837✔
3300
  int32_t action = 0;
7,837✔
3301
  int64_t streamId = pMsg->streamId;
7,837✔
3302
  SStreamTask* pTask = (SStreamTask*)pMsg;
7,837✔
3303
  int8_t  stopped = 0;
7,837✔
3304

3305
  msttDebug("start to handle task abnormal status %d", pTask->status);
7,837✔
3306
  
3307
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
7,837✔
3308
  if (NULL == pStatus) {
7,837!
UNCOV
3309
    msttInfo("stream no longer exists in streamMap, try to undeploy current task, idx:%d", pMsg->taskIdx);
×
UNCOV
3310
    TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
×
3311
    return;
7,442✔
3312
  }
3313

3314
  stopped = atomic_load_8(&pStatus->stopped);
7,837✔
3315
  if (stopped) {
7,837!
UNCOV
3316
    msttInfo("stream stopped %d, try to undeploy current task, idx:%d", stopped, pMsg->taskIdx);
×
UNCOV
3317
    TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
×
UNCOV
3318
    return;
×
3319
  }
3320
  
3321
  switch (pMsg->status) {
7,837!
3322
    case STREAM_STATUS_INIT:      
7,821✔
3323
      if (STREAM_TRIGGER_TASK != pMsg->type) {
7,821✔
3324
        msttTrace("task status is INIT and not trigger task, ignore it, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
7,173!
3325
        return;
7,173✔
3326
      }
3327
      
3328
      if (INT64_MIN == pStatus->lastActionTs) {
648!
UNCOV
3329
        msttDebug("task still not deployed, ignore it, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
×
UNCOV
3330
        return;
×
3331
      }
3332
      
3333
      if ((pCtx->currTs - pStatus->lastActionTs) < STREAM_ACT_MIN_DELAY_MSEC) {
648✔
3334
        msttDebug("task wait not enough between actions, currTs:%" PRId64 ", lastTs:%" PRId64, pCtx->currTs, pStatus->lastActionTs);
269✔
3335
        return;
269✔
3336
      }
3337

3338
      if (STREAM_IS_RUNNING(pStatus)) {
379!
UNCOV
3339
        msttDebug("stream already running, ignore status: %s", gStreamStatusStr[pTask->status]);
×
3340
      } else if (GOT_SNODE(pCtx->pReq->snodeId) && msmCheckStreamStartCond(streamId, pCtx->pReq->snodeId)) {
379!
3341
        TAOS_CHECK_EXIT(msmGrpAddActionStart(pCtx->actionStm, streamId, &pStatus->triggerTask->id));
340!
3342
      }
3343
      break;
379✔
3344
    case STREAM_STATUS_FAILED:
16✔
3345
      //STREAMTODO ADD ERRCODE HANDLE
3346
      msttInfo("task failed with error:%s, try to undeploy current task, idx:%d", tstrerror(pMsg->errorCode), pMsg->taskIdx);
16!
3347
      TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
16!
3348
      break;
16✔
3349
    default:
×
UNCOV
3350
      break;
×
3351
  }
3352

3353
_exit:
395✔
3354

3355
  if (code) {
395!
UNCOV
3356
    msmStopStreamByError(streamId, pStatus, code, pCtx->currTs);
×
UNCOV
3357
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3358
  }
3359
}
3360

3361
void msmHandleStatusUpdateErr(SStmGrpCtx* pCtx, EStmErrType err, SStmTaskStatusMsg* pStatus) {
194✔
3362
  int32_t code = TSDB_CODE_SUCCESS;
194✔
3363
  int32_t lino = 0;
194✔
3364
  SStreamTask* pTask = (SStreamTask*)pStatus;
194✔
3365
  int64_t streamId = pStatus->streamId;
194✔
3366

3367
  msttInfo("start to handle task status update exception, type: %d", err);
194!
3368
  
3369
  // STREAMTODO
3370

3371
  if (STM_ERR_TASK_NOT_EXISTS == err || STM_ERR_STREAM_STOPPED == err) {
194!
3372
    TAOS_CHECK_EXIT(msmGrpAddActionUndeploy(pCtx, streamId, pTask));
194!
3373
  }
3374

3375
_exit:
194✔
3376

3377
  if (code) {
194!
3378
    // IGNORE STOP STREAM BY ERROR  
UNCOV
3379
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3380
  }
3381
}
194✔
3382

3383
void msmChkHandleTriggerOperations(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask, SStmTaskStatus* pStatus) {
3,084✔
3384
  int32_t code = TSDB_CODE_SUCCESS;
3,084✔
3385
  int32_t lino = 0;
3,084✔
3386
  SStmStatus* pStream = (SStmStatus*)pStatus->pStream;
3,084✔
3387

3388
  if (1 == atomic_val_compare_exchange_8(&pStream->triggerNeedUpdate, 1, 0)) {
3,084!
UNCOV
3389
    TAOS_CHECK_EXIT(msmGrpAddActionUpdateTrigger(pCtx->actionStm, pTask->streamId));
×
3390
  }
3391
  
3392
  SArray* userRecalcList = NULL;
3,084✔
3393
  if (atomic_load_ptr(&pStream->userRecalcList)) {
3,084!
UNCOV
3394
    taosWLockLatch(&pStream->userRecalcLock);
×
UNCOV
3395
    if (pStream->userRecalcList) {
×
UNCOV
3396
      userRecalcList = pStream->userRecalcList;
×
UNCOV
3397
      pStream->userRecalcList = NULL;
×
3398
    }
UNCOV
3399
    taosWUnLockLatch(&pStream->userRecalcLock);
×
3400
    
UNCOV
3401
    if (userRecalcList) {
×
3402
      TAOS_CHECK_EXIT(msmGrpAddActionRecalc(pCtx, pTask->streamId, userRecalcList));
×
3403
    }
3404
  }
3405

3406
  if (pTask->detailStatus >= 0 && pCtx->pReq->pTriggerStatus) {
3,084!
3407
    mstWaitLock(&pStatus->detailStatusLock, false);
1,547✔
3408
    if (NULL == pStatus->detailStatus) {
1,547✔
3409
      pStatus->detailStatus = taosMemoryCalloc(1, sizeof(SSTriggerRuntimeStatus));
262!
3410
      if (NULL == pStatus->detailStatus) {
262!
UNCOV
3411
        taosWUnLockLatch(&pStatus->detailStatusLock);
×
UNCOV
3412
        TSDB_CHECK_NULL(pStatus->detailStatus, code, lino, _exit, terrno);
×
3413
      }
3414
    }
3415
    
3416
    memcpy(pStatus->detailStatus, taosArrayGet(pCtx->pReq->pTriggerStatus, pTask->detailStatus), sizeof(SSTriggerRuntimeStatus));
1,547✔
3417
    taosWUnLockLatch(&pStatus->detailStatusLock);
1,547✔
3418
  }
3419

3420
_exit:
1,537✔
3421

3422
  if (code) {
3,084!
3423
    // IGNORE STOP STREAM BY ERROR
UNCOV
3424
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3425
  }
3426
}
3,084✔
3427

3428
int32_t msmNormalHandleStatusUpdate(SStmGrpCtx* pCtx) {
1,447✔
3429
  int32_t code = TSDB_CODE_SUCCESS;
1,447✔
3430
  int32_t lino = 0;
1,447✔
3431
  int32_t num = taosArrayGetSize(pCtx->pReq->pStreamStatus);
1,447✔
3432

3433
  mstDebug("NORMAL: start to handle stream group %d tasks status, taskNum:%d", pCtx->pReq->streamGId, num);
1,447✔
3434

3435
  for (int32_t i = 0; i < num; ++i) {
18,876✔
3436
    SStmTaskStatusMsg* pTask = taosArrayGet(pCtx->pReq->pStreamStatus, i);
17,429✔
3437
    msttDebug("task status %s got on dnode %d, taskIdx:%d", gStreamStatusStr[pTask->status], pCtx->pReq->dnodeId, pTask->taskIdx);
17,429✔
3438
    
3439
    SStmTaskStatus** ppStatus = taosHashGet(mStreamMgmt.taskMap, &pTask->streamId, sizeof(pTask->streamId) + sizeof(pTask->taskId));
17,429✔
3440
    if (NULL == ppStatus) {
17,429✔
3441
      msttWarn("task no longer exists in taskMap, will try to undeploy current task, taskIdx:%d", pTask->taskIdx);
49!
3442
      msmHandleStatusUpdateErr(pCtx, STM_ERR_TASK_NOT_EXISTS, pTask);
49✔
3443
      continue;
49✔
3444
    }
3445

3446
    SStmStatus* pStream = (SStmStatus*)(*ppStatus)->pStream;
17,380✔
3447
    int8_t stopped = atomic_load_8(&pStream->stopped);
17,380✔
3448
    if (stopped) {
17,380✔
3449
      msttWarn("stream already stopped %d, will try to undeploy current task, taskIdx:%d", stopped, pTask->taskIdx);
145!
3450
      msmHandleStatusUpdateErr(pCtx, STM_ERR_STREAM_STOPPED, pTask);
145✔
3451
      continue;
145✔
3452
    }
3453

3454
    if ((pTask->seriousId != (*ppStatus)->id.seriousId) || (pTask->nodeId != (*ppStatus)->id.nodeId)) {
17,235!
3455
      msttInfo("task mismatch with it in taskMap, will try to rm it, current seriousId:%" PRId64 ", nodeId:%d", 
×
3456
          (*ppStatus)->id.seriousId, (*ppStatus)->id.nodeId);
3457
          
UNCOV
3458
      msmHandleStatusUpdateErr(pCtx, STM_ERR_TASK_NOT_EXISTS, pTask);
×
UNCOV
3459
      continue;
×
3460
    }
3461

3462
    if ((*ppStatus)->status != pTask->status) {
17,235✔
3463
      if (STREAM_STATUS_RUNNING == pTask->status) {
2,640✔
3464
        (*ppStatus)->runningStartTs = pCtx->currTs;
1,066✔
3465
      } else if (MST_IS_RUNNER_GETTING_READY(pTask) && STREAM_IS_REDEPLOY_RUNNER((*ppStatus)->flags)) {
1,574!
3466
        if (pStream->triggerTask) {
×
UNCOV
3467
          atomic_store_8(&pStream->triggerNeedUpdate, 1);
×
3468
        }
3469
        
3470
        STREAM_CLR_FLAG((*ppStatus)->flags, STREAM_FLAG_REDEPLOY_RUNNER);
×
3471
      }
3472
    }
3473
    
3474
    (*ppStatus)->errCode = pTask->errorCode;
17,235✔
3475
    (*ppStatus)->status = pTask->status;
17,235✔
3476
    (*ppStatus)->lastUpTs = pCtx->currTs;
17,235✔
3477
    
3478
    if (STREAM_STATUS_RUNNING != pTask->status) {
17,235✔
3479
      msmHandleTaskAbnormalStatus(pCtx, pTask, *ppStatus);
7,837✔
3480
    }
3481
    
3482
    if (STREAM_TRIGGER_TASK == pTask->type) {
17,235✔
3483
      msmChkHandleTriggerOperations(pCtx, pTask, *ppStatus);
3,084✔
3484
    }
3485
  }
3486

3487
_exit:
1,447✔
3488

3489
  if (code) {
1,447!
3490
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3491
  }
3492

3493
  return code;
1,447✔
3494
}
3495

3496
int32_t msmWatchRecordNewTask(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
×
3497
  int32_t code = TSDB_CODE_SUCCESS;
×
3498
  int32_t lino = 0;
×
3499
  int64_t streamId = pTask->streamId;
×
3500
  SStreamObj* pStream = NULL;
×
3501

3502
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3503
  if (NULL == pStatus) {
×
3504
    SStmStatus status = {0};
×
UNCOV
3505
    TAOS_CHECK_EXIT(mndAcquireStreamById(pCtx->pMnode, streamId, &pStream));
×
3506
    TSDB_CHECK_NULL(pStream, code, lino, _exit, TSDB_CODE_MND_STREAM_NOT_EXIST);
×
3507
    if (STREAM_IS_VIRTUAL_TABLE(pStream->pCreate->triggerTblType, pStream->pCreate->flags)) {
×
3508
      mndReleaseStream(pCtx->pMnode, pStream);
×
3509
      msttDebug("virtual table task ignored, status:%s", gStreamStatusStr[pTask->status]);
×
UNCOV
3510
      return code;
×
3511
    }
3512

UNCOV
3513
    TAOS_CHECK_EXIT(msmInitStmStatus(pCtx, &status, pStream, true));
×
3514
    mndReleaseStream(pCtx->pMnode, pStream);
×
3515

UNCOV
3516
    TAOS_CHECK_EXIT(taosHashPut(mStreamMgmt.streamMap, &streamId, sizeof(streamId), &status, sizeof(status)));
×
3517
    pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3518
    TSDB_CHECK_NULL(pStatus, code, lino, _exit, terrno);
×
3519
    msttDebug("stream added to streamMap cause of new task status:%s", gStreamStatusStr[pTask->status]);
×
3520
  }
3521

UNCOV
3522
  SStmTaskStatus* pNewTask = NULL;
×
3523
  switch (pTask->type) {
×
3524
    case STREAM_READER_TASK: {
×
3525
      SArray* pList = STREAM_IS_TRIGGER_READER(pTask->flags) ? pStatus->trigReaders : pStatus->calcReaders;
×
UNCOV
3526
      if (NULL == pList) {
×
3527
        mstsError("%sReader list is NULL", STREAM_IS_TRIGGER_READER(pTask->flags) ? "trig" : "calc");
×
3528
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3529
      }
3530
      int32_t readerSize = STREAM_IS_TRIGGER_READER(pTask->flags) ? pStatus->trigReaderNum : pStatus->calcReaderNum;
×
UNCOV
3531
      if (taosArrayGetSize(pList) >= readerSize) {
×
UNCOV
3532
        mstsError("%sReader list is already full, size:%d, expSize:%d", STREAM_IS_TRIGGER_READER(pTask->flags) ? "trig" : "calc",
×
3533
            (int32_t)taosArrayGetSize(pList), readerSize);
3534
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3535
      }
3536
      
3537
      SStmTaskStatus taskStatus = {0};
×
UNCOV
3538
      taskStatus.pStream = pStatus;
×
3539
      mstSetTaskStatusFromMsg(pCtx, &taskStatus, pTask);
×
UNCOV
3540
      pNewTask = taosArrayPush(pList, &taskStatus);
×
UNCOV
3541
      TSDB_CHECK_NULL(pNewTask, code, lino, _exit, terrno);
×
3542

UNCOV
3543
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, pNewTask));
×
UNCOV
3544
      TAOS_CHECK_EXIT(msmSTAddToVgroupMapImpl(streamId, pNewTask, STREAM_IS_TRIGGER_READER(pTask->flags)));
×
3545
      break;
×
3546
    }
3547
    case STREAM_TRIGGER_TASK: {
×
3548
      taosMemoryFreeClear(pStatus->triggerTask);
×
UNCOV
3549
      pStatus->triggerTask = taosMemoryCalloc(1, sizeof(*pStatus->triggerTask));
×
3550
      TSDB_CHECK_NULL(pStatus->triggerTask, code, lino, _exit, terrno);
×
UNCOV
3551
      pStatus->triggerTask->pStream = pStatus;
×
3552
      mstSetTaskStatusFromMsg(pCtx, pStatus->triggerTask, pTask);
×
3553
      pNewTask = pStatus->triggerTask;
×
3554

UNCOV
3555
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, pNewTask));
×
3556
      TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pNewTask, 0));
×
3557
      break;
×
3558
    }
UNCOV
3559
    case STREAM_RUNNER_TASK:{
×
3560
      if (NULL == pStatus->runners[pTask->deployId]) {
×
3561
        mstsError("deploy %d runner list is NULL", pTask->deployId);
×
3562
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3563
      }
3564
      if (taosArrayGetSize(pStatus->runners[pTask->deployId]) >= pStatus->runnerNum) {
×
UNCOV
3565
        mstsError("deploy %d runner list is already full, size:%d, expSize:%d", pTask->deployId, 
×
3566
            (int32_t)taosArrayGetSize(pStatus->runners[pTask->deployId]), pStatus->runnerNum);
UNCOV
3567
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
3568
      }    
3569
      
3570
      SStmTaskStatus taskStatus = {0};
×
UNCOV
3571
      taskStatus.pStream = pStatus;
×
UNCOV
3572
      mstSetTaskStatusFromMsg(pCtx, &taskStatus, pTask);
×
3573
      pNewTask = taosArrayPush(pStatus->runners[pTask->deployId], &taskStatus);
×
UNCOV
3574
      TSDB_CHECK_NULL(pNewTask, code, lino, _exit, terrno);
×
3575

3576
      TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, pNewTask));
×
UNCOV
3577
      TAOS_CHECK_EXIT(msmSTAddToSnodeMapImpl(streamId, pNewTask, pTask->deployId));
×
UNCOV
3578
      break;
×
3579
    }
UNCOV
3580
    default: {
×
UNCOV
3581
      msttError("invalid task type:%d in task status", pTask->type);
×
UNCOV
3582
      TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);
×
UNCOV
3583
      break;
×
3584
    }
3585
  }
3586

UNCOV
3587
_exit:
×
3588

UNCOV
3589
  if (code) {
×
UNCOV
3590
    msttError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3591
  } else {
UNCOV
3592
    msttDebug("new task recored to taskMap/streamMap, task status:%s", gStreamStatusStr[pTask->status]);
×
3593
  }
3594

UNCOV
3595
  return code;
×
3596
}
3597

UNCOV
3598
int32_t msmWatchHandleStatusUpdate(SStmGrpCtx* pCtx) {
×
UNCOV
3599
  int32_t code = TSDB_CODE_SUCCESS;
×
UNCOV
3600
  int32_t lino = 0;
×
UNCOV
3601
  int32_t num = taosArrayGetSize(pCtx->pReq->pStreamStatus);
×
3602

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

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

UNCOV
3609
    if (pTask->taskId >= mStreamMgmt.lastTaskId) {
×
UNCOV
3610
      mStreamMgmt.lastTaskId = pTask->taskId + 1;
×
3611
    }
3612
    
UNCOV
3613
    SStmTaskStatus** ppStatus = taosHashGet(mStreamMgmt.taskMap, &pTask->streamId, sizeof(pTask->streamId) + sizeof(pTask->taskId));
×
UNCOV
3614
    if (NULL == ppStatus) {
×
UNCOV
3615
      msttInfo("task still not in taskMap, will try to add it, taskIdx:%d", pTask->taskIdx);
×
3616
      
UNCOV
3617
      TAOS_CHECK_EXIT(msmWatchRecordNewTask(pCtx, pTask));
×
3618
      
UNCOV
3619
      continue;
×
3620
    }
3621
    
UNCOV
3622
    (*ppStatus)->status = pTask->status;
×
UNCOV
3623
    (*ppStatus)->lastUpTs = pCtx->currTs;
×
3624
  }
3625

UNCOV
3626
_exit:
×
3627

UNCOV
3628
  if (code) {
×
UNCOV
3629
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3630
  }
3631

UNCOV
3632
  return code;
×
3633
}
3634

3635
void msmRspAddStreamStart(int64_t streamId, SStmGrpCtx* pCtx, int32_t streamNum, SStmAction *pAction) {
340✔
3636
  int32_t code = TSDB_CODE_SUCCESS;
340✔
3637
  int32_t lino = 0;
340✔
3638
  if (NULL == pCtx->pRsp->start.taskList) {
340✔
3639
    pCtx->pRsp->start.taskList = taosArrayInit(streamNum, sizeof(SStreamTaskStart));
143✔
3640
    TSDB_CHECK_NULL(pCtx->pRsp->start.taskList, code, lino, _exit, terrno);
143!
3641
  }
3642

3643
  SStmTaskId* pId = &pAction->start.triggerId;
340✔
3644
  SStreamTaskStart start = {0};
340✔
3645
  start.task.type = STREAM_TRIGGER_TASK;
340✔
3646
  start.task.streamId = streamId;
340✔
3647
  start.task.taskId = pId->taskId;
340✔
3648
  start.task.seriousId = pId->seriousId;
340✔
3649
  start.task.nodeId = pId->nodeId;
340✔
3650
  start.task.taskIdx = pId->taskIdx;
340✔
3651

3652
  TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->start.taskList, &start), code, lino, _exit, terrno);
680!
3653
  TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(streamId, pCtx->currTs));
340!
3654

3655
  mstsDebug("stream START added to dnode %d hb rsp, triggerTaskId:%" PRIx64, pId->nodeId, pId->taskId);
340✔
3656

3657
  return;
340✔
3658

3659
_exit:
×
3660

UNCOV
3661
  mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3662
}
3663

3664

3665
void msmRspAddStreamUndeploy(int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
84✔
3666
  int32_t code = TSDB_CODE_SUCCESS;
84✔
3667
  int32_t lino = 0;
84✔
3668
  int32_t dropNum = taosArrayGetSize(pAction->undeploy.taskList);
84✔
3669
  if (NULL == pCtx->pRsp->undeploy.taskList) {
84✔
3670
    pCtx->pRsp->undeploy.taskList = taosArrayInit(dropNum, sizeof(SStreamTaskUndeploy));
73✔
3671
    TSDB_CHECK_NULL(pCtx->pRsp->undeploy.taskList, code, lino, _exit, terrno);
73!
3672
  }
3673

3674
  SStreamTaskUndeploy undeploy;
3675
  for (int32_t i = 0; i < dropNum; ++i) {
294✔
3676
    SStreamTask* pTask = (SStreamTask*)taosArrayGetP(pAction->undeploy.taskList, i);
210✔
3677
    undeploy.task = *pTask;
210✔
3678
    undeploy.undeployMsg.doCheckpoint = pAction->undeploy.doCheckpoint;
210✔
3679
    undeploy.undeployMsg.doCleanup = pAction->undeploy.doCleanup;
210✔
3680

3681
    TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->undeploy.taskList, &undeploy), code, lino, _exit, terrno);
420!
3682
    TAOS_CHECK_EXIT(msmUpdateStreamLastActTs(streamId, pCtx->currTs));
210!
3683

3684
    msttDebug("task UNDEPLOY added to hb rsp, doCheckpoint:%d, doCleanup:%d", undeploy.undeployMsg.doCheckpoint, undeploy.undeployMsg.doCleanup);
210✔
3685
  }
3686

3687
  return;
84✔
3688

UNCOV
3689
_exit:
×
3690

3691
  mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3692
}
3693

UNCOV
3694
void msmRspAddTriggerUpdate(SMnode * pMnode, int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
×
3695
  int32_t code = TSDB_CODE_SUCCESS;
×
3696
  int32_t lino = 0;
×
3697

3698
  SStmStatus* pStream = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
3699
  if (NULL == pStream) {
×
3700
    mstsDebug("stream already not exists in streamMap, ignore trigger update, streamRemain:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
UNCOV
3701
    return;
×
3702
  }
3703

3704
  if (NULL == pStream->triggerTask) {
×
UNCOV
3705
    mstsWarn("no triggerTask exists, ignore trigger update, stopped:%d", atomic_load_8(&pStream->stopped));
×
UNCOV
3706
    return;
×
3707
  }
3708

3709
  SStreamMgmtRsp rsp = {0};
×
UNCOV
3710
  rsp.reqId = INT64_MIN;
×
3711
  rsp.header.msgType = STREAM_MSG_UPDATE_RUNNER;
×
3712
  rsp.task.streamId = streamId;
×
UNCOV
3713
  rsp.task.taskId = pStream->triggerTask->id.taskId;
×
3714

UNCOV
3715
  TAOS_CHECK_EXIT(msmBuildTriggerRunnerTargets(pMnode, pStream, streamId, &rsp.cont.runnerList));  
×
3716

UNCOV
3717
  if (NULL == pCtx->pRsp->rsps.rspList) {
×
UNCOV
3718
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
UNCOV
3719
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
×
3720
  }
3721

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

UNCOV
3724
_exit:
×
3725

UNCOV
3726
  if (code) {
×
UNCOV
3727
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3728
  } else {
UNCOV
3729
    mstsDebug("trigger update rsp added, runnerNum:%d", (int32_t)taosArrayGetSize(rsp.cont.runnerList));
×
3730
  }
3731
}
3732

UNCOV
3733
void msmRspAddUserRecalc(SMnode * pMnode, int64_t streamId, SStmGrpCtx* pCtx, SStmAction *pAction) {
×
UNCOV
3734
  int32_t code = TSDB_CODE_SUCCESS;
×
UNCOV
3735
  int32_t lino = 0;
×
3736

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

UNCOV
3743
  if (NULL == pStream->triggerTask) {
×
UNCOV
3744
    mstsWarn("no triggerTask exists, ignore trigger update, stopped:%d", atomic_load_8(&pStream->stopped));
×
UNCOV
3745
    return;
×
3746
  }
3747

UNCOV
3748
  SStreamMgmtRsp rsp = {0};
×
UNCOV
3749
  rsp.reqId = INT64_MIN;
×
UNCOV
3750
  rsp.header.msgType = STREAM_MSG_USER_RECALC;
×
UNCOV
3751
  rsp.task.streamId = streamId;
×
UNCOV
3752
  rsp.task.taskId = pStream->triggerTask->id.taskId;
×
UNCOV
3753
  TSWAP(rsp.cont.recalcList, pAction->recalc.recalcList);
×
3754

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

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

UNCOV
3762
_exit:
×
3763

UNCOV
3764
  if (code) {
×
UNCOV
3765
    mstsError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3766
  } else {
UNCOV
3767
    mstsDebug("user recalc rsp added, recalcNum:%d", (int32_t)taosArrayGetSize(rsp.cont.recalcList));
×
3768
  }
3769
}
3770

3771

3772
int32_t msmHandleHbPostActions(SStmGrpCtx* pCtx) {
216✔
3773
  int32_t code = TSDB_CODE_SUCCESS;
216✔
3774
  int32_t lino = 0;
216✔
3775
  void* pIter = NULL;
216✔
3776
  int32_t streamNum = taosHashGetSize(pCtx->actionStm);
216✔
3777

3778
  mstDebug("start to handle stream group %d post actions", pCtx->pReq->streamGId);
216✔
3779

3780
  while (1) {
424✔
3781
    pIter = taosHashIterate(pCtx->actionStm, pIter);
640✔
3782
    if (pIter == NULL) {
640✔
3783
      break;
216✔
3784
    }
3785

3786
    int64_t* pStreamId = taosHashGetKey(pIter, NULL);
424✔
3787
    SStmAction *pAction = (SStmAction *)pIter;
424✔
3788
    
3789
    if (STREAM_ACT_UNDEPLOY & pAction->actions) {
424✔
3790
      msmRspAddStreamUndeploy(*pStreamId, pCtx, pAction);
84✔
3791
      continue;
84✔
3792
    }
3793

3794
    if (STREAM_ACT_UPDATE_TRIGGER & pAction->actions) {
340!
3795
      msmRspAddTriggerUpdate(pCtx->pMnode, *pStreamId, pCtx, pAction);
×
3796
    }
3797

3798
    if (STREAM_ACT_RECALC & pAction->actions) {
340!
UNCOV
3799
      msmRspAddUserRecalc(pCtx->pMnode, *pStreamId, pCtx, pAction);
×
3800
    }
3801

3802
    if (STREAM_ACT_START & pAction->actions) {
340!
3803
      msmRspAddStreamStart(*pStreamId, pCtx, streamNum, pAction);
340✔
3804
    }
3805
  }
3806
  
3807
_exit:
216✔
3808

3809
  if (pIter) {
216!
UNCOV
3810
    taosHashCancelIterate(pCtx->actionStm, pIter);
×
3811
  }
3812

3813
  if (code) {
216!
3814
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3815
  }
3816

3817
  return code;
216✔
3818
}
3819

3820
int32_t msmCheckUpdateDnodeTs(SStmGrpCtx* pCtx) {
44,293✔
3821
  int32_t  code = TSDB_CODE_SUCCESS;
44,293✔
3822
  int32_t  lino = 0;
44,293✔
3823
  int64_t* lastTs = NULL;
44,293✔
3824
  bool     noExists = false;
44,293✔
3825

3826
  while (true) {
3827
    lastTs = taosHashGet(mStreamMgmt.dnodeMap, &pCtx->pReq->dnodeId, sizeof(pCtx->pReq->dnodeId));
46,616✔
3828
    if (NULL == lastTs) {
46,616✔
3829
      if (noExists) {
2,658✔
3830
        mstWarn("Got unknown dnode %d hb msg, may be dropped", pCtx->pReq->dnodeId);
335!
3831
        TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NODE_NOT_EXISTS);
335!
3832
      }
3833

3834
      noExists = true;
2,323✔
3835
      TAOS_CHECK_EXIT(msmSTAddDnodesToMap(pCtx->pMnode));
2,323!
3836
      
3837
      continue;
2,323✔
3838
    }
3839

UNCOV
3840
    while (true) {
×
3841
      int64_t lastTsValue = atomic_load_64(lastTs);
43,958✔
3842
      if (pCtx->currTs > lastTsValue) {
43,958✔
3843
        if (lastTsValue == atomic_val_compare_exchange_64(lastTs, lastTsValue, pCtx->currTs)) {
43,951!
3844
          mstDebug("dnode %d lastUpTs updated", pCtx->pReq->dnodeId);
43,951✔
3845
          return code;
43,951✔
3846
        }
3847

UNCOV
3848
        continue;
×
3849
      }
3850

3851
      return code;
7✔
3852
    }
3853

3854
    break;
3855
  }
3856

3857
_exit:
335✔
3858

3859
  if (code) {
335!
3860
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
335!
3861
  }
3862

3863
  return code;  
335✔
3864
}
3865

UNCOV
3866
void msmWatchCheckStreamMap(SStmGrpCtx* pCtx) {
×
UNCOV
3867
  SStmStatus* pStatus = NULL;
×
UNCOV
3868
  int32_t trigReaderNum = 0;
×
3869
  int32_t calcReaderNum = 0;
×
UNCOV
3870
  int32_t runnerNum = 0;
×
UNCOV
3871
  int64_t streamId = 0;
×
UNCOV
3872
  void* pIter = NULL;
×
3873
  while (true) {
3874
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
×
3875
    if (NULL == pIter) {
×
3876
      return;
×
3877
    }
3878

UNCOV
3879
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
UNCOV
3880
    pStatus = (SStmStatus*)pIter;
×
3881

UNCOV
3882
    if (NULL == pStatus->triggerTask) {
×
UNCOV
3883
      mstsWarn("no trigger task recored, deployTimes:%" PRId64, pStatus->deployTimes);
×
UNCOV
3884
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
UNCOV
3885
      continue;
×
3886
    }
3887
    
UNCOV
3888
    trigReaderNum = taosArrayGetSize(pStatus->trigReaders);
×
UNCOV
3889
    if (pStatus->trigReaderNum != trigReaderNum) {
×
UNCOV
3890
      mstsWarn("trigReaderNum %d mis-match with expected %d", trigReaderNum, pStatus->trigReaderNum);
×
UNCOV
3891
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
UNCOV
3892
      continue;
×
3893
    }
3894

UNCOV
3895
    calcReaderNum = taosArrayGetSize(pStatus->calcReaders);
×
UNCOV
3896
    if (pStatus->calcReaderNum != calcReaderNum) {
×
3897
      mstsWarn("calcReaderNum %d mis-match with expected %d", calcReaderNum, pStatus->calcReaderNum);
×
UNCOV
3898
      msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
UNCOV
3899
      continue;
×
3900
    }
3901

UNCOV
3902
    for (int32_t i = 0; i < pStatus->runnerDeploys; ++i) {
×
UNCOV
3903
      runnerNum = taosArrayGetSize(pStatus->runners[i]);
×
UNCOV
3904
      if (runnerNum != pStatus->runnerNum) {
×
UNCOV
3905
        mstsWarn("runner deploy %d runnerNum %d mis-match with expected %d", i, runnerNum, pStatus->runnerNum);
×
UNCOV
3906
        msmStopStreamByError(streamId, pStatus, TSDB_CODE_MND_STREAM_TASK_LOST, pCtx->currTs);
×
UNCOV
3907
        continue;
×
3908
      }
3909
    }
3910
  }
3911
}
3912

UNCOV
3913
int32_t msmWatchHandleEnding(SStmGrpCtx* pCtx, bool watchError) {
×
UNCOV
3914
  int32_t code = TSDB_CODE_SUCCESS;
×
UNCOV
3915
  int32_t lino = 0;
×
3916

UNCOV
3917
  if (0 != atomic_val_compare_exchange_8(&mStreamMgmt.watch.ending, 0, 1)) {
×
UNCOV
3918
    return code;
×
3919
  }
3920

3921
  while (atomic_load_32(&mStreamMgmt.watch.processing) > 1) {
×
3922
    (void)sched_yield();
×
3923
  }
3924

UNCOV
3925
  if (watchError) {
×
UNCOV
3926
    taosHashClear(mStreamMgmt.vgroupMap);
×
UNCOV
3927
    taosHashClear(mStreamMgmt.snodeMap);
×
UNCOV
3928
    taosHashClear(mStreamMgmt.taskMap);
×
UNCOV
3929
    taosHashClear(mStreamMgmt.streamMap);
×
UNCOV
3930
    mstInfo("watch error happends, clear all maps");
×
UNCOV
3931
    goto _exit;
×
3932
  }
3933

3934
  if (0 == atomic_load_8(&mStreamMgmt.watch.taskRemains)) {
×
UNCOV
3935
    mstInfo("no stream tasks remain during watch state");
×
3936
    goto _exit;
×
3937
  }
3938

UNCOV
3939
  msmWatchCheckStreamMap(pCtx);
×
3940

UNCOV
3941
_exit:
×
3942

UNCOV
3943
  mStreamMgmt.lastTaskId += 100000;
×
3944

UNCOV
3945
  mstInfo("watch state end, new taskId begin from:%" PRIx64, mStreamMgmt.lastTaskId);
×
3946

UNCOV
3947
  msmSetInitRuntimeState(MND_STM_STATE_NORMAL);
×
3948

UNCOV
3949
  if (code) {
×
UNCOV
3950
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3951
  }
3952

UNCOV
3953
  return code;
×
3954
}
3955

3956

UNCOV
3957
int32_t msmWatchHandleHbMsg(SStmGrpCtx* pCtx) {
×
3958
  int32_t code = TSDB_CODE_SUCCESS;
×
3959
  int32_t lino = 0;
×
3960
  SStreamHbMsg* pReq = pCtx->pReq;
×
3961

UNCOV
3962
  atomic_add_fetch_32(&mStreamMgmt.watch.processing, 1);
×
3963
  
3964
  if (atomic_load_8(&mStreamMgmt.watch.ending)) {
×
3965
    goto _exit;
×
3966
  }
3967

UNCOV
3968
  TAOS_CHECK_EXIT(msmCheckUpdateDnodeTs(pCtx));
×
UNCOV
3969
  if (GOT_SNODE(pReq->snodeId)) {
×
UNCOV
3970
    TAOS_CHECK_EXIT(msmUpdateSnodeUpTs(pCtx));
×
3971
  }
3972

UNCOV
3973
  if (taosArrayGetSize(pReq->pStreamStatus) > 0) {
×
UNCOV
3974
    atomic_store_8(&mStreamMgmt.watch.taskRemains, 1);
×
UNCOV
3975
    TAOS_CHECK_EXIT(msmWatchHandleStatusUpdate(pCtx));
×
3976
  }
3977

UNCOV
3978
  if ((pCtx->currTs - MND_STREAM_GET_LAST_TS(STM_EVENT_ACTIVE_BEGIN)) > MST_ISOLATION_DURATION) {
×
UNCOV
3979
    TAOS_CHECK_EXIT(msmWatchHandleEnding(pCtx, false));
×
3980
  }
3981

UNCOV
3982
_exit:
×
3983

UNCOV
3984
  atomic_sub_fetch_32(&mStreamMgmt.watch.processing, 1);
×
3985
  
UNCOV
3986
  if (code) {
×
UNCOV
3987
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
3988

UNCOV
3989
    msmWatchHandleEnding(pCtx, true);
×
3990
  }
3991

UNCOV
3992
  return code;
×
3993
}
3994

3995
int32_t msmCheckDeployTrigReader(SStmGrpCtx* pCtx, SStmStatus* pStatus, SStmTaskStatusMsg* pTask, int32_t vgId, int32_t vgNum) {
82✔
3996
  int32_t code = TSDB_CODE_SUCCESS;
82✔
3997
  int32_t lino = 0;
82✔
3998
  bool    readerExists = false;
82✔
3999
  int64_t streamId = pTask->streamId;
82✔
4000

4001
  int32_t readerNum = taosArrayGetSize(pStatus->trigReaders);
82✔
4002
  for (int32_t i = 0; i < readerNum; ++i) {
121✔
4003
    SStmTaskStatus* pReader = (SStmTaskStatus*)taosArrayGet(pStatus->trigReaders, i);
84✔
4004
    if (pReader->id.nodeId == vgId) {
84✔
4005
      readerExists = true;
45✔
4006
      break;
45✔
4007
    }
4008
  }
4009

4010
  if (!readerExists) {
82✔
4011
    if (NULL == pStatus->trigOReaders) {
37✔
4012
      pStatus->trigOReaders = taosArrayInit(vgNum, sizeof(SStmTaskStatus));
36✔
4013
      TSDB_CHECK_NULL(pStatus->trigOReaders, code, lino, _exit, terrno);
36!
4014
    }
4015
    
4016
    SStmTaskStatus* pState = taosArrayReserve(pStatus->trigOReaders, 1);
37✔
4017
    TAOS_CHECK_EXIT(msmTDAddSingleTrigReader(pCtx, pState, vgId, pStatus, NULL, streamId));
37!
4018
    TAOS_CHECK_EXIT(msmSTAddToTaskMap(pCtx, streamId, NULL, pState));
37!
4019
    TAOS_CHECK_EXIT(msmSTAddToVgroupMap(pCtx, streamId, NULL, pState, true));
37!
4020
  }
4021

4022
_exit:
82✔
4023

4024
  if (code) {
82!
UNCOV
4025
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4026
  }
4027

4028
  return code;
82✔
4029
}
4030

4031
int32_t msmProcessDeployOrigReader(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
81✔
4032
  int32_t code = TSDB_CODE_SUCCESS;
81✔
4033
  int32_t lino = 0;
81✔
4034
  int32_t vgId = 0;
81✔
4035
  int64_t streamId = pTask->streamId;
81✔
4036
  SArray* pTbs = pTask->pMgmtReq->cont.fullTableNames;
81✔
4037
  int32_t tbNum = taosArrayGetSize(pTbs);
81✔
4038
  SStreamDbTableName* pName = NULL;
81✔
4039
  SSHashObj* pDbVgroups = NULL;
81✔
4040
  SStreamMgmtRsp rsp = {0};
81✔
4041
  rsp.reqId = pTask->pMgmtReq->reqId;
81✔
4042
  rsp.header.msgType = STREAM_MSG_ORIGTBL_READER_INFO;
81✔
4043
  int32_t iter = 0;
81✔
4044
  void* p = NULL;
81✔
4045
  SSHashObj* pVgs = NULL;
81✔
4046
  SStreamMgmtReq* pMgmtReq = NULL;
81✔
4047
  int8_t stopped = 0;
81✔
4048
  
4049
  TSWAP(pTask->pMgmtReq, pMgmtReq);
81✔
4050
  rsp.task = *(SStreamTask*)pTask;
81✔
4051

4052
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
81✔
4053
  if (NULL == pStatus) {
81!
4054
    mstsError("stream not deployed, remainStreams:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
4055
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_NOT_RUNNING);
×
4056
  }
4057

4058
  stopped = atomic_load_8(&pStatus->stopped);
81✔
4059
  if (stopped) {
81!
4060
    msttInfo("stream stopped %d, ignore deploy trigger reader, vgId:%d", stopped, vgId);
×
UNCOV
4061
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_STOPPED);
×
4062
  }
4063

4064
  if (tbNum <= 0) {
81!
UNCOV
4065
    mstsWarn("empty table list in origReader req, array:%p", pTbs);
×
UNCOV
4066
    goto _exit;
×
4067
  }
4068

4069
  int32_t oReaderNum = taosArrayGetSize(pStatus->trigOReaders);
81✔
4070
  if (oReaderNum > 0) {
81!
UNCOV
4071
    mstsWarn("origReaders already exits, num:%d", oReaderNum);
×
UNCOV
4072
    goto _exit;
×
4073
  }
4074

4075
  TAOS_CHECK_EXIT(mstBuildDBVgroupsMap(pCtx->pMnode, &pDbVgroups));
81!
4076
  rsp.cont.vgIds = taosArrayInit(tbNum, sizeof(int32_t));
81✔
4077
  TSDB_CHECK_NULL(rsp.cont.vgIds, code, lino, _exit, terrno);
81!
4078

4079
  pVgs = tSimpleHashInit(tbNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
81✔
4080
  TSDB_CHECK_NULL(pVgs, code, lino, _exit, terrno);
81!
4081
  
4082
  for (int32_t i = 0; i < tbNum; ++i) {
221✔
4083
    pName = (SStreamDbTableName*)taosArrayGet(pTbs, i);
140✔
4084
    TAOS_CHECK_EXIT(mstGetTableVgId(pDbVgroups, pName->dbFName, pName->tbName, &vgId));
140!
4085
    TSDB_CHECK_NULL(taosArrayPush(rsp.cont.vgIds, &vgId), code, lino, _exit, terrno);
280!
4086
    TAOS_CHECK_EXIT(tSimpleHashPut(pVgs, &vgId, sizeof(vgId), &vgId, sizeof(vgId)));
140!
4087
  }
4088

4089
  int32_t vgNum = tSimpleHashGetSize(pVgs);
81✔
4090
  while (true) {
4091
    p = tSimpleHashIterate(pVgs, p, &iter);
163✔
4092
    if (NULL == p) {
163✔
4093
      break;
81✔
4094
    }
4095
    
4096
    TAOS_CHECK_EXIT(msmCheckDeployTrigReader(pCtx, pStatus, pTask, *(int32_t*)p, vgNum));
82!
4097
  }
4098
  
4099
  vgNum = taosArrayGetSize(pStatus->trigOReaders);
81✔
4100
  rsp.cont.readerList = taosArrayInit(vgNum, sizeof(SStreamTaskAddr));
81✔
4101
  TSDB_CHECK_NULL(rsp.cont.readerList, code, lino, _exit, terrno);
81!
4102

4103
  SStreamTaskAddr addr;
4104
  for (int32_t i = 0; i < vgNum; ++i) {
118✔
4105
    SStmTaskStatus* pOTask = taosArrayGet(pStatus->trigOReaders, i);
37✔
4106
    addr.taskId = pOTask->id.taskId;
37✔
4107
    addr.nodeId = pOTask->id.nodeId;
37✔
4108
    addr.epset = mndGetVgroupEpsetById(pCtx->pMnode, pOTask->id.nodeId);
37✔
4109
    TSDB_CHECK_NULL(taosArrayPush(rsp.cont.readerList, &addr), code, lino, _exit, terrno);
74!
4110
    mstsDebug("the %dth otrigReader src added to trigger's virtual orig readerList, TASK:%" PRIx64 " nodeId:%d", i, addr.taskId, addr.nodeId);
37!
4111
  }
4112

4113
  if (NULL == pCtx->pRsp->rsps.rspList) {
81!
UNCOV
4114
    pCtx->pRsp->rsps.rspList = taosArrayInit(2, sizeof(SStreamMgmtRsp));
×
UNCOV
4115
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
×
4116
  }
4117

4118
  TSDB_CHECK_NULL(taosArrayPush(pCtx->pRsp->rsps.rspList, &rsp), code, lino, _exit, terrno);
162!
4119

4120
_exit:
81✔
4121

4122
  tFreeSStreamMgmtReq(pMgmtReq);
81✔
4123
  taosMemoryFree(pMgmtReq);
81!
4124

4125
  tSimpleHashCleanup(pVgs);
81✔
4126

4127
  if (code) {
81!
UNCOV
4128
    mndStreamDestroySStreamMgmtRsp(&rsp);
×
UNCOV
4129
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4130
  }
4131

4132
  mstDestroyDbVgroupsHash(pDbVgroups);
81✔
4133

4134
  return code;
81✔
4135
}
4136

4137
int32_t msmHandleTaskMgmtReq(SStmGrpCtx* pCtx, SStmTaskStatusMsg* pTask) {
81✔
4138
  int32_t code = TSDB_CODE_SUCCESS;
81✔
4139
  int32_t lino = 0;
81✔
4140

4141
  switch (pTask->pMgmtReq->type) {
81!
4142
    case STREAM_MGMT_REQ_TRIGGER_ORIGTBL_READER:
81✔
4143
      TAOS_CHECK_EXIT(msmProcessDeployOrigReader(pCtx, pTask));
81!
4144
      break;
81✔
UNCOV
4145
    default:
×
UNCOV
4146
      msttError("Invalid mgmtReq type:%d", pTask->pMgmtReq->type);
×
UNCOV
4147
      code = TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
UNCOV
4148
      break;
×
4149
  }
4150

4151
_exit:
81✔
4152

4153
  if (code) {
81!
UNCOV
4154
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4155
  }
4156

4157
  return code;
81✔
4158
}
4159

4160
int32_t msmHandleStreamRequests(SStmGrpCtx* pCtx) {
29✔
4161
  int32_t code = TSDB_CODE_SUCCESS;
29✔
4162
  int32_t lino = 0;
29✔
4163
  SStreamHbMsg* pReq = pCtx->pReq;
29✔
4164
  SStmTaskStatusMsg* pTask = NULL;
29✔
4165
  
4166
  int32_t reqNum = taosArrayGetSize(pReq->pStreamReq);
29✔
4167
  if (reqNum > 0 && NULL == pCtx->pRsp->rsps.rspList) {
29!
4168
    pCtx->pRsp->rsps.rspList = taosArrayInit(reqNum, sizeof(SStreamMgmtRsp));
29✔
4169
    TSDB_CHECK_NULL(pCtx->pRsp->rsps.rspList, code, lino, _exit, terrno);
29!
4170
  }
4171
  
4172
  for (int32_t i = 0; i < reqNum; ++i) {
110✔
4173
    int32_t idx = *(int32_t*)taosArrayGet(pReq->pStreamReq, i);
81✔
4174
    pTask = (SStmTaskStatusMsg*)taosArrayGet(pReq->pStreamStatus, idx);
81✔
4175
    if (NULL == pTask) {
81!
UNCOV
4176
      mstError("idx %d is NULL, reqNum:%d", idx, reqNum);
×
UNCOV
4177
      continue;
×
4178
    }
4179

4180
    if (NULL == pTask->pMgmtReq) {
81!
UNCOV
4181
      msttError("idx %d without mgmtReq", idx);
×
UNCOV
4182
      continue;
×
4183
    }
4184

4185
    TAOS_CHECK_EXIT(msmHandleTaskMgmtReq(pCtx, pTask));
81!
4186
  }
4187

4188
_exit:
29✔
4189

4190
  if (code) {
29!
UNCOV
4191
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4192
  }
4193

4194
  return code;
29✔
4195
}
4196

4197
int32_t msmNormalHandleHbMsg(SStmGrpCtx* pCtx) {
44,293✔
4198
  int32_t code = TSDB_CODE_SUCCESS;
44,293✔
4199
  int32_t lino = 0;
44,293✔
4200
  SStreamHbMsg* pReq = pCtx->pReq;
44,293✔
4201

4202
  TAOS_CHECK_EXIT(msmCheckUpdateDnodeTs(pCtx));
44,293✔
4203
  if (GOT_SNODE(pReq->snodeId)) {
43,958✔
4204
    TAOS_CHECK_EXIT(msmUpdateSnodeUpTs(pCtx));
6,664!
4205
  }
4206
  
4207
  if (atomic_load_64(&mStreamMgmt.actionQ->qRemainNum) > 0 && 0 == taosWTryLockLatch(&mStreamMgmt.actionQLock)) {
43,958✔
4208
    code = msmHandleStreamActions(pCtx);
72✔
4209
    taosWUnLockLatch(&mStreamMgmt.actionQLock);
72✔
4210
    TAOS_CHECK_EXIT(code);
72!
4211
  }
4212

4213
  if (taosArrayGetSize(pReq->pStreamReq) > 0 && mstWaitLock(&mStreamMgmt.actionQLock, false)) {
43,958!
4214
    code = msmHandleStreamRequests(pCtx);
29✔
4215
    taosWUnLockLatch(&mStreamMgmt.actionQLock);
29✔
4216
    TAOS_CHECK_EXIT(code);
29!
4217
  }
4218

4219
  if (atomic_load_32(&mStreamMgmt.toDeployVgTaskNum) > 0) {
43,958✔
4220
    TAOS_CHECK_EXIT(msmGrpAddDeployVgTasks(pCtx));
159!
4221
  } else {
4222
    TAOS_CHECK_EXIT(msmUpdateVgroupsUpTs(pCtx));
43,799!
4223
  }
4224

4225
  if (atomic_load_32(&mStreamMgmt.toDeploySnodeTaskNum) > 0 && GOT_SNODE(pReq->snodeId)) {
43,958✔
4226
    TAOS_CHECK_EXIT(msmGrpAddDeploySnodeTasks(pCtx));
109!
4227
  }
4228

4229
  if (taosHashGetSize(pCtx->deployStm) > 0) {
43,958✔
4230
    TAOS_CHECK_EXIT(msmRspAddStreamsDeploy(pCtx));
104!
4231
  }
4232

4233
  if (taosArrayGetSize(pReq->pStreamStatus) > 0) {
43,958✔
4234
    TAOS_CHECK_EXIT(msmNormalHandleStatusUpdate(pCtx));
1,447!
4235
  }
4236

4237
  if (taosHashGetSize(pCtx->actionStm) > 0) {
43,958✔
4238
    TAOS_CHECK_EXIT(msmHandleHbPostActions(pCtx));
216!
4239
  }
4240

4241
_exit:
43,958✔
4242

4243
  if (code) {
44,293✔
4244
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
335!
4245
  }
4246

4247
  return code;
44,293✔
4248
}
4249

4250
void msmEncodeStreamHbRsp(int32_t code, SRpcHandleInfo *pRpcInfo, SMStreamHbRspMsg* pRsp, SRpcMsg* pMsg) {
44,293✔
4251
  int32_t lino = 0;
44,293✔
4252
  int32_t tlen = 0;
44,293✔
4253
  void   *buf = NULL;
44,293✔
4254

4255
  if (TSDB_CODE_SUCCESS != code) {
44,293✔
4256
    goto _exit;
335✔
4257
  }
4258

4259
  tEncodeSize(tEncodeStreamHbRsp, pRsp, tlen, code);
43,958!
4260
  if (code < 0) {
43,958!
UNCOV
4261
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(code));
×
UNCOV
4262
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
4263
  }
4264

4265
  buf = rpcMallocCont(tlen + sizeof(SStreamMsgGrpHeader));
43,958✔
4266
  if (buf == NULL) {
43,958!
UNCOV
4267
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(terrno));
×
UNCOV
4268
    TAOS_CHECK_EXIT(terrno);    
×
4269
  }
4270

4271
  ((SStreamMsgGrpHeader *)buf)->streamGid = pRsp->streamGId;
43,958✔
4272
  void *abuf = POINTER_SHIFT(buf, sizeof(SStreamMsgGrpHeader));
43,958✔
4273

4274
  SEncoder encoder;
4275
  tEncoderInit(&encoder, abuf, tlen);
43,958✔
4276
  if ((code = tEncodeStreamHbRsp(&encoder, pRsp)) < 0) {
43,958!
UNCOV
4277
    rpcFreeCont(buf);
×
UNCOV
4278
    buf = NULL;
×
UNCOV
4279
    tEncoderClear(&encoder);
×
UNCOV
4280
    mstError("encode stream hb msg rsp failed, code:%s", tstrerror(code));
×
UNCOV
4281
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_INTERNAL_ERROR);    
×
4282
  }
4283
  tEncoderClear(&encoder);
43,958✔
4284

4285
_exit:
44,293✔
4286

4287
  pMsg->code = code;
44,293✔
4288
  pMsg->info = *pRpcInfo;
44,293✔
4289
  if (TSDB_CODE_SUCCESS == code) {
44,293✔
4290
    pMsg->contLen = tlen + sizeof(SStreamMsgGrpHeader);
43,958✔
4291
    pMsg->pCont = buf;
43,958✔
4292
  }
4293
}
44,293✔
4294

4295

4296
int32_t msmHandleStreamHbMsg(SMnode* pMnode, int64_t currTs, SStreamHbMsg* pHb, SRpcMsg *pReq, SRpcMsg* pRspMsg) {
45,084✔
4297
  int32_t code = TSDB_CODE_SUCCESS;
45,084✔
4298

4299
  if (0 == atomic_load_8(&mStreamMgmt.active)) {
45,084✔
4300
    mstWarn("mnode stream is NOT active, ignore stream hb from dnode %d streamGid %d", pHb->dnodeId, pHb->streamGId);
791!
4301
    return code;
791✔
4302
  }
4303

4304
  mstWaitLock(&mStreamMgmt.runtimeLock, true);
44,293✔
4305

4306
  SMStreamHbRspMsg rsp = {0};
44,293✔
4307
  int32_t tidx = streamGetThreadIdx(mStreamMgmt.threadNum, pHb->streamGId);
44,293✔
4308
  SStmGrpCtx* pCtx = &mStreamMgmt.tCtx[tidx].grpCtx[pHb->streamGId];
44,293✔
4309

4310
  pCtx->tidx = tidx;
44,293✔
4311
  pCtx->pMnode = pMnode;
44,293✔
4312
  pCtx->currTs = currTs;
44,293✔
4313
  pCtx->pReq = pHb;
44,293✔
4314
  pCtx->pRsp = &rsp;
44,293✔
4315
  pCtx->deployStm = mStreamMgmt.tCtx[pCtx->tidx].deployStm[pHb->streamGId];
44,293✔
4316
  pCtx->actionStm = mStreamMgmt.tCtx[pCtx->tidx].actionStm[pHb->streamGId];
44,293✔
4317
  
4318
  switch (atomic_load_8(&mStreamMgmt.state)) {
44,293!
UNCOV
4319
    case MND_STM_STATE_WATCH:
×
UNCOV
4320
      code = msmWatchHandleHbMsg(pCtx);
×
UNCOV
4321
      break;
×
4322
    case MND_STM_STATE_NORMAL:
44,293✔
4323
      code = msmNormalHandleHbMsg(pCtx);
44,293✔
4324
      break;
44,293✔
UNCOV
4325
    default:
×
UNCOV
4326
      mstError("Invalid stream state: %d", mStreamMgmt.state);
×
UNCOV
4327
      code = TSDB_CODE_MND_STREAM_INTERNAL_ERROR;
×
UNCOV
4328
      break;
×
4329
  }
4330

4331
  msmEncodeStreamHbRsp(code, &pReq->info, &rsp, pRspMsg);
44,293✔
4332

4333
  msmCleanStreamGrpCtx(pHb);
44,293✔
4334
  msmClearStreamToDeployMaps(pHb);
44,293✔
4335

4336
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
44,293✔
4337

4338
  tFreeSMStreamHbRspMsg(&rsp);
44,293✔
4339

4340
  return code;
44,293✔
4341
}
4342

4343
void msmHandleBecomeLeader(SMnode *pMnode) {
2,407✔
4344
  if (tsDisableStream) {
2,407!
UNCOV
4345
    return;
×
4346
  }
4347

4348
  mstInfo("start to process mnode become leader");
2,407!
4349
  
4350
  streamAddVnodeLeader(MNODE_HANDLE);
2,407✔
4351
  
4352
  taosWLockLatch(&mStreamMgmt.runtimeLock);
2,407✔
4353
  msmDestroyRuntimeInfo(pMnode);
2,407✔
4354
  msmInitRuntimeInfo(pMnode);
2,407✔
4355
  taosWUnLockLatch(&mStreamMgmt.runtimeLock);
2,407✔
4356

4357
  atomic_store_8(&mStreamMgmt.active, 1);
2,407✔
4358
}
4359

4360
void msmHandleBecomeNotLeader(SMnode *pMnode) {  
469✔
4361
  if (tsDisableStream) {
469!
UNCOV
4362
    return;
×
4363
  }
4364

4365
  mstInfo("start to process mnode become not leader");
469!
4366

4367
  streamRemoveVnodeLeader(MNODE_HANDLE);
469✔
4368

4369
  if (atomic_val_compare_exchange_8(&mStreamMgmt.active, 1, 0)) {
469✔
4370
    taosWLockLatch(&mStreamMgmt.runtimeLock);
3✔
4371
    msmDestroyRuntimeInfo(pMnode);
3✔
4372
    mStreamMgmt.stat.inactiveTimes++;
3✔
4373
    taosWUnLockLatch(&mStreamMgmt.runtimeLock);
3✔
4374
  }
4375
}
4376

4377

UNCOV
4378
static void msmRedeployStream(int64_t streamId, SStmStatus* pStatus) {
×
UNCOV
4379
  if (1 == atomic_val_compare_exchange_8(&pStatus->stopped, 1, 0)) {
×
4380
    mstsInfo("try to reset and redeploy stream, deployTimes:%" PRId64, pStatus->deployTimes);
×
4381
    mstPostStreamAction(mStreamMgmt.actionQ, streamId, pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
×
4382
  } else {
UNCOV
4383
    mstsWarn("stream stopped %d already changed", atomic_load_8(&pStatus->stopped));
×
4384
  }
UNCOV
4385
}
×
4386

4387
static bool msmCheckStreamAssign(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
19✔
4388
  int32_t code = TSDB_CODE_SUCCESS;
19✔
4389
  int32_t lino = 0;
19✔
4390
  SStreamObj* pStream = pObj;
19✔
4391
  SSnodeObj* pSnode = p1;
19✔
4392
  SArray** ppRes = p2;
19✔
4393

4394
  if (pStream->mainSnodeId == pSnode->id) {
19✔
4395
    if (NULL == *ppRes) {
2!
4396
      int32_t streamNum = sdbGetSize(pMnode->pSdb, SDB_STREAM);
2✔
4397
      *ppRes = taosArrayInit(streamNum, POINTER_BYTES);
2✔
4398
      TSDB_CHECK_NULL(*ppRes, code, lino, _exit, terrno);
2!
4399
    }
4400

4401
    TSDB_CHECK_NULL(taosArrayPush(*ppRes, &pStream), code, lino, _exit, terrno);
4!
4402
  }
4403

4404
  return true;
19✔
4405

UNCOV
4406
_exit:
×
4407

UNCOV
4408
  if (code) {
×
UNCOV
4409
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4410
  }  
4411

UNCOV
4412
  *(int32_t*)p3 = code;
×
4413

UNCOV
4414
  return false;
×
4415
}
4416

4417

4418
int32_t msmCheckSnodeReassign(SMnode *pMnode, SSnodeObj* pSnode, SArray** ppRes) {
154✔
4419
  int32_t code = TSDB_CODE_SUCCESS;
154✔
4420
  int32_t lino = 0;
154✔
4421
  
4422
  sdbTraverse(pMnode->pSdb, SDB_STREAM, msmCheckStreamAssign, pSnode, ppRes, &code);
154✔
4423
  TAOS_CHECK_EXIT(code);
154!
4424

4425
  int32_t streamNum = taosArrayGetSize(*ppRes);
154✔
4426
  if (streamNum > 0 && 0 == pSnode->replicaId) {
154!
4427
    mstError("snode %d has no replica while %d streams assigned", pSnode->id, streamNum);
×
4428
    TAOS_CHECK_EXIT(TSDB_CODE_MND_STREAM_SNODE_IN_USE);
×
4429
  }
4430

4431
  //STREAMTODO CHECK REPLICA UPDATED OR NOT
4432

4433
_exit:
154✔
4434

4435
  if (code) {
154!
UNCOV
4436
    mstError("%s failed at line %d, error:%s", __FUNCTION__, lino, tstrerror(code));
×
4437
  }  
4438

4439
  return code;
154✔
4440
}
4441

4442
static bool msmCheckLoopStreamSdb(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
769✔
4443
  SStreamObj* pStream = pObj;
769✔
4444
  int64_t streamId = pStream->pCreate->streamId;
769✔
4445
  SStmStatus* pStatus = taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
769✔
4446
  SStmCheckStatusCtx* pCtx = (SStmCheckStatusCtx*)p1;
769✔
4447
  int8_t userDropped = atomic_load_8(&pStream->userDropped), userStopped = atomic_load_8(&pStream->userStopped);
769✔
4448
  
4449
  if ((userDropped || userStopped) && (NULL == pStatus)) {
769!
UNCOV
4450
    mstsDebug("stream userDropped %d userStopped %d and not in streamMap, ignore it", userDropped, userStopped);
×
UNCOV
4451
    return true;
×
4452
  }
4453
  
4454
  if (pStatus && !MST_STM_PASS_ISOLATION(pStream, pStatus)) {
769✔
4455
    mstsDebug("stream not pass isolation time, updateTime:%" PRId64 ", lastActionTs:%" PRId64 ", currentTs %" PRId64 ", ignore check it", 
666✔
4456
        pStream->updateTime, pStatus->lastActionTs, mStreamMgmt.hCtx.currentTs);
4457
    return true;
666✔
4458
  }
4459

4460
  if (NULL == pStatus && !MST_STM_STATIC_PASS_ISOLATION(pStream)) {
103✔
4461
    mstsDebug("stream not pass static isolation time, updateTime:%" PRId64 ", currentTs %" PRId64 ", ignore check it", 
14!
4462
        pStream->updateTime, mStreamMgmt.hCtx.currentTs);
4463
    return true;
14✔
4464
  }  
4465

4466
  if (pStatus) {
89✔
4467
    if (userDropped || userStopped || MST_IS_USER_STOPPED(atomic_load_8(&pStatus->stopped))) {
88!
UNCOV
4468
      (void)msmRemoveStreamFromMaps(pMnode, streamId);
×
4469
    }
4470

4471
    return true;
88✔
4472
  }
4473

4474
  mstPostStreamAction(mStreamMgmt.actionQ, streamId, pStream->pCreate->name, NULL, false, STREAM_ACT_DEPLOY);
1✔
4475

4476
  return true;
1✔
4477
}
4478

4479
void msmCheckLoopStreamMap(SMnode *pMnode) {
71✔
4480
  SStmStatus* pStatus = NULL;
71✔
4481
  void* pIter = NULL;
71✔
4482
  int8_t stopped = 0;
71✔
4483
  int64_t streamId = 0;
71✔
4484
  
4485
  while (true) {
4486
    pIter = taosHashIterate(mStreamMgmt.streamMap, pIter);
583✔
4487
    if (NULL == pIter) {
583✔
4488
      break;
71✔
4489
    }
4490

4491
    pStatus = (SStmStatus*)pIter;
512✔
4492

4493
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
512✔
4494
    stopped = atomic_load_8(&pStatus->stopped);
512✔
4495
    if (MST_IS_USER_STOPPED(stopped)) {
512!
4496
      mstsDebug("stream already stopped by user, deployTimes:%" PRId64, pStatus->deployTimes);
8✔
4497
      (void)msmRemoveStreamFromMaps(pMnode, streamId);
8✔
4498
      continue;
8✔
4499
    }
4500

4501
    if (!sdbCheckExists(pMnode->pSdb, SDB_STREAM, pStatus->streamName)) {
504!
UNCOV
4502
      mstsDebug("stream already not exists, deployTimes:%" PRId64, pStatus->deployTimes);
×
UNCOV
4503
      (void)msmRemoveStreamFromMaps(pMnode, *(int64_t*)taosHashGetKey(pIter, NULL));
×
UNCOV
4504
      continue;
×
4505
    }
4506

4507
    if (MST_IS_ERROR_STOPPED(stopped)) {
504✔
4508
      if (mStreamMgmt.hCtx.currentTs < pStatus->fatalRetryTs) {
18!
UNCOV
4509
        mstsDebug("stream already stopped by error %s, retried times:%" PRId64 ", next time not reached, currTs:%" PRId64 ", nextRetryTs:%" PRId64,
×
4510
            tstrerror(pStatus->fatalError), pStatus->fatalRetryTimes, mStreamMgmt.hCtx.currentTs, pStatus->fatalRetryTs);
4511
            
UNCOV
4512
        MND_STREAM_SET_LAST_TS(STM_EVENT_STM_TERR, mStreamMgmt.hCtx.currentTs);
×
UNCOV
4513
        continue;
×
4514
      }
4515

4516
      mstPostStreamAction(mStreamMgmt.actionQ, *(int64_t*)taosHashGetKey(pIter, NULL), pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
18✔
4517
      continue;
18✔
4518
    }
4519

4520
    if (MST_IS_GRANT_STOPPED(stopped) && TSDB_CODE_SUCCESS == grantCheckExpire(TSDB_GRANT_STREAMS)) {
486!
UNCOV
4521
      mstPostStreamAction(mStreamMgmt.actionQ, *(int64_t*)taosHashGetKey(pIter, NULL), pStatus->streamName, NULL, false, STREAM_ACT_DEPLOY);
×
UNCOV
4522
      continue;
×
4523
    }
4524
  }
4525
}
71✔
4526

4527
void msmCheckStreamsStatus(SMnode *pMnode) {
377✔
4528
  SStmCheckStatusCtx ctx = {0};
377✔
4529

4530
  mstDebug("start to check streams status, currTs:%" PRId64, mStreamMgmt.hCtx.currentTs);
377✔
4531
  
4532
  if (MST_READY_FOR_SDB_LOOP()) {
377!
4533
    mstDebug("ready to check sdb loop, lastLoopSdbTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_SDB].ts);
101✔
4534
    sdbTraverse(pMnode->pSdb, SDB_STREAM, msmCheckLoopStreamSdb, &ctx, NULL, NULL);
101✔
4535
    MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_SDB, mStreamMgmt.hCtx.currentTs);
101✔
4536
  }
4537

4538
  if (MST_READY_FOR_MAP_LOOP()) {
377!
4539
    mstDebug("ready to check map loop, lastLoopMapTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_MAP].ts);
71✔
4540
    msmCheckLoopStreamMap(pMnode);
71✔
4541
    MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_MAP, mStreamMgmt.hCtx.currentTs);
71✔
4542
  }
4543
}
377✔
4544

4545
void msmCheckTaskListStatus(int64_t streamId, SStmTaskStatus** pList, int32_t taskNum) {
6,442✔
4546
  for (int32_t i = 0; i < taskNum; ++i) {
12,890✔
4547
    SStmTaskStatus* pTask = *(pList + i);
6,466✔
4548

4549
    if (atomic_load_8(&((SStmStatus*)pTask->pStream)->stopped)) {
6,466✔
4550
      continue;
6,420✔
4551
    }
4552
    
4553
    if (!MST_PASS_ISOLATION(pTask->lastUpTs, 1)) {
6,106✔
4554
      continue;
6,060✔
4555
    }
4556

4557
    int64_t noUpTs = mStreamMgmt.hCtx.currentTs - pTask->lastUpTs;
46✔
4558
    if (STREAM_RUNNER_TASK == pTask->type || STREAM_TRIGGER_TASK == pTask->type) {
46✔
4559
      mstsWarn("%s TASK:%" PRIx64 " status not updated for %" PRId64 "ms, will try to redeploy it", 
18!
4560
          gStreamTaskTypeStr[pTask->type], pTask->id.taskId, noUpTs);
4561
          
4562
      msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_TASK_LOST, mStreamMgmt.hCtx.currentTs);
18✔
4563
      break;
18✔
4564
    }
4565

4566
    mstsInfo("%s TASK:%" PRIx64 " status not updated for %" PRId64 "ms, will try to redeploy it", 
28!
4567
        gStreamTaskTypeStr[pTask->type], pTask->id.taskId, noUpTs);
4568

4569
    int64_t newSid = atomic_add_fetch_64(&pTask->id.seriousId, 1);
28✔
4570
    mstsDebug("task %" PRIx64 " SID updated to %" PRIx64, pTask->id.taskId, newSid);
28!
4571

4572
    SStmTaskAction task = {0};
28✔
4573
    task.streamId = streamId;
28✔
4574
    task.id = pTask->id;
28✔
4575
    task.flag = pTask->flags;
28✔
4576
    task.type = pTask->type;
28✔
4577
    
4578
    mstPostTaskAction(mStreamMgmt.actionQ, &task, STREAM_ACT_DEPLOY);
28✔
4579
  }
4580
}
6,442✔
4581

4582
void msmCheckVgroupStreamStatus(SHashObj* pStreams) {
496✔
4583
  void* pIter = NULL;
496✔
4584
  SStmVgStreamStatus* pVg = NULL;
496✔
4585
  int64_t streamId = 0;
496✔
4586
  
4587
  while (true) {
1,533✔
4588
    pIter = taosHashIterate(pStreams, pIter);
2,029✔
4589
    if (NULL == pIter) {
2,029✔
4590
      break;
496✔
4591
    }
4592

4593
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
1,533✔
4594
    pVg = (SStmVgStreamStatus*)pIter;
1,533✔
4595

4596
    int32_t taskNum = taosArrayGetSize(pVg->trigReaders);
1,533✔
4597
    if (taskNum > 0) {
1,533✔
4598
      msmCheckTaskListStatus(streamId, taosArrayGet(pVg->trigReaders, 0), taskNum);
1,252✔
4599
    }
4600

4601
    taskNum = taosArrayGetSize(pVg->calcReaders);
1,533✔
4602
    if (taskNum > 0) {
1,533✔
4603
      msmCheckTaskListStatus(streamId, taosArrayGet(pVg->calcReaders, 0), taskNum);
590✔
4604
    }
4605
  }
4606
}
496✔
4607

4608
void msmHandleVgroupLost(SMnode *pMnode, int32_t vgId, SStmVgroupStatus* pVg) {
5✔
4609
  int64_t streamId = 0;
5✔
4610
  void* pIter = NULL;
5✔
4611
  SStmVgStreamStatus* pStream = NULL;
5✔
4612

4613
  if (!MST_PASS_ISOLATION(pVg->lastUpTs, 5)) {
5!
4614
    mstDebug("vgroup %d lost and still in watch time, lastUpTs:%" PRId64 ", streamNum:%d", vgId, pVg->lastUpTs, (int32_t)taosHashGetSize(pVg->streamTasks));
5✔
4615
    return;
5✔
4616
  }
4617

4618
  
4619
  while (true) {
UNCOV
4620
    pIter = taosHashIterate(pVg->streamTasks, pIter);
×
UNCOV
4621
    if (NULL == pIter) {
×
UNCOV
4622
      break;
×
4623
    }
4624

UNCOV
4625
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
×
4626
    
UNCOV
4627
    msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_VGROUP_LOST, mStreamMgmt.hCtx.currentTs);
×
4628
  }
4629

UNCOV
4630
  taosHashClear(pVg->streamTasks);
×
4631
}
4632

4633

4634
void msmCheckVgroupStatus(SMnode *pMnode) {
377✔
4635
  void* pIter = NULL;
377✔
4636
  
4637
  while (true) {
1,497✔
4638
    pIter = taosHashIterate(mStreamMgmt.vgroupMap, pIter);
1,874✔
4639
    if (NULL == pIter) {
1,874✔
4640
      break;
377✔
4641
    }
4642

4643
    int32_t vgId = *(int32_t*)taosHashGetKey(pIter, NULL);
1,497✔
4644
    if ((vgId % MND_STREAM_ISOLATION_PERIOD_NUM) != mStreamMgmt.hCtx.slotIdx) {
1,497✔
4645
      continue;
996✔
4646
    }
4647
    
4648
    SStmVgroupStatus* pVg = (SStmVgroupStatus*)pIter;
501✔
4649

4650
    if (MST_PASS_ISOLATION(pVg->lastUpTs, 1)) {
501✔
4651
      mstWarn("vgroup %d lost, lastUpTs:%" PRId64 ", streamNum:%d", vgId, pVg->lastUpTs, (int32_t)taosHashGetSize(pVg->streamTasks));
5!
4652
      
4653
      msmHandleVgroupLost(pMnode, vgId, pVg);
5✔
4654
      continue;
5✔
4655
    }
4656

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

4659
    msmCheckVgroupStreamStatus(pVg->streamTasks);
496✔
4660
  }
4661
}
377✔
4662

4663
void msmHandleRunnerRedeploy(int64_t streamId, SStmSnodeStreamStatus* pStream, int32_t* deployNum, int32_t* deployId) {
10✔
4664
  *deployNum = 0;
10✔
4665
  
4666
  for (int32_t i = 0; i < MND_STREAM_RUNNER_DEPLOY_NUM; ++i) {
38✔
4667
    if (pStream->runners[i]) {
29✔
4668
      int32_t taskNum = taosArrayGetSize(pStream->runners[i]);
11✔
4669
      for (int32_t t = 0; t < taskNum; ++t) {
21✔
4670
        SStmTaskStatus* pTask = taosArrayGetP(pStream->runners[i], t);
11✔
4671
        int8_t stopped = atomic_load_8(&((SStmStatus*)pTask->pStream)->stopped);
11✔
4672
        if (stopped) {
11✔
4673
          mstsDebug("stream already stopped %d, ignore it", stopped);
1!
4674
          *deployNum = 0;
1✔
4675
          return;
1✔
4676
        }
4677

4678
        int64_t newSid = atomic_add_fetch_64(&pTask->id.seriousId, 1);
10✔
4679
        mstsDebug("task %" PRIx64 " SID updated to %" PRIx64, pTask->id.taskId, newSid);
10!
4680
      }
4681
      
4682
      deployId[*deployNum] = i;
10✔
4683
      (*deployNum)++;
10✔
4684
    }
4685
  }
4686
}
4687

4688
void msmHandleSnodeLost(SMnode *pMnode, SStmSnodeStatus* pSnode) {
31✔
4689
  pSnode->runnerThreadNum = -1;
31✔
4690

4691
  (void)msmSTAddSnodesToMap(pMnode);
31✔
4692

4693
  int64_t streamId = 0;
31✔
4694
  void* pIter = NULL;
31✔
4695
  SStmSnodeStreamStatus* pStream = NULL;
31✔
4696
  int32_t deployNum = 0;
31✔
4697
  SStmTaskAction task = {0};
31✔
4698
  
4699
  while (true) {
4700
    pIter = taosHashIterate(pSnode->streamTasks, pIter);
43✔
4701
    if (NULL == pIter) {
43✔
4702
      break;
31✔
4703
    }
4704

4705
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
12✔
4706
    
4707
    task.streamId = streamId;
12✔
4708
    
4709
    pStream = (SStmSnodeStreamStatus*)pIter;
12✔
4710
    if (pStream->trigger) {
12✔
4711
      int8_t stopped = atomic_load_8(&((SStmStatus*)pStream->trigger->pStream)->stopped);
2✔
4712
      if (stopped) {
2!
UNCOV
4713
        mstsDebug("stream already stopped %d, ignore it", stopped);
×
UNCOV
4714
        continue;
×
4715
      }
4716

4717
      mstsInfo("snode lost with trigger task %" PRIx64 ", will try to restart current stream", pStream->trigger->id.taskId);
2!
4718
      
4719
      msmStopStreamByError(streamId, NULL, TSDB_CODE_MND_STREAM_SNODE_LOST, mStreamMgmt.hCtx.currentTs);
2✔
4720
    } else {
4721
      msmHandleRunnerRedeploy(streamId, pStream, &task.deployNum, task.deployId);
10✔
4722
      
4723
      if (task.deployNum > 0) {
10✔
4724
        //task.triggerStatus = pStream->trigger;
4725
        task.multiRunner = true;
9✔
4726
        task.type = STREAM_RUNNER_TASK;
9✔
4727
        
4728
        mstPostTaskAction(mStreamMgmt.actionQ, &task, STREAM_ACT_DEPLOY);
9✔
4729
        
4730
        mstsInfo("runner tasks %d redeploys added to actionQ", task.deployNum);
9!
4731
      }
4732
    }
4733
  }
4734

4735
  taosHashClear(pSnode->streamTasks);
31✔
4736
}
31✔
4737

4738

4739
void msmCheckSnodeStreamStatus(SHashObj* pStreams) {
202✔
4740
  void* pIter = NULL;
202✔
4741
  SStmSnodeStreamStatus* pSnode = NULL;
202✔
4742
  int64_t streamId = 0;
202✔
4743
  
4744
  while (true) {
4745
    pIter = taosHashIterate(pStreams, pIter);
1,481✔
4746
    if (NULL == pIter) {
1,481✔
4747
      break;
202✔
4748
    }
4749

4750
    streamId = *(int64_t*)taosHashGetKey(pIter, NULL);
1,279✔
4751
    pSnode = (SStmSnodeStreamStatus*)pIter;
1,279✔
4752

4753
    if (NULL != pSnode->trigger) {
1,279✔
4754
      msmCheckTaskListStatus(streamId, &pSnode->trigger, 1);
1,153✔
4755
    }
4756

4757
    for (int32_t i = 0; i < MND_STREAM_RUNNER_DEPLOY_NUM; ++i) {
5,116✔
4758
      int32_t taskNum = taosArrayGetSize(pSnode->runners[i]);
3,837✔
4759
      if (taskNum > 0) {
3,837✔
4760
        msmCheckTaskListStatus(streamId, taosArrayGet(pSnode->runners[i], 0), taskNum);
3,447✔
4761
      }
4762
    }
4763
  }
4764
}
202✔
4765

4766

4767
void msmCheckSnodeStatus(SMnode *pMnode) {
377✔
4768
  void* pIter = NULL;
377✔
4769
  
4770
  while (true) {
717✔
4771
    pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter);
1,094✔
4772
    if (NULL == pIter) {
1,094✔
4773
      break;
377✔
4774
    }
4775

4776
    int32_t snodeId = *(int32_t*)taosHashGetKey(pIter, NULL);
717✔
4777
    if ((snodeId % MND_STREAM_ISOLATION_PERIOD_NUM) != mStreamMgmt.hCtx.slotIdx) {
717✔
4778
      continue;
469✔
4779
    }
4780

4781
    mstDebug("start to check snode %d status, currTs:%" PRId64, snodeId, mStreamMgmt.hCtx.currentTs);
248✔
4782
    
4783
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
248✔
4784
    if (NULL == pSnode->streamTasks) {
248✔
4785
      mstDebug("ignore snode %d health check since empty tasks", snodeId);
17!
4786
      continue;
17✔
4787
    }
4788
    
4789
    if (MST_PASS_ISOLATION(pSnode->lastUpTs, 1)) {
231✔
4790
      mstInfo("snode %d lost, lastUpTs:%" PRId64 ", runnerThreadNum:%d, streamNum:%d", 
29!
4791
          snodeId, pSnode->lastUpTs, pSnode->runnerThreadNum, (int32_t)taosHashGetSize(pSnode->streamTasks));
4792
      
4793
      msmHandleSnodeLost(pMnode, pSnode);
29✔
4794
      continue;
29✔
4795
    }
4796
    
4797
    mstDebug("snode %d online, try to check tasks status, currTs:%" PRId64 ", lastUpTs:%" PRId64, snodeId, mStreamMgmt.hCtx.currentTs, pSnode->lastUpTs);
202✔
4798

4799
    msmCheckSnodeStreamStatus(pSnode->streamTasks);
202✔
4800
  }
4801
}
377✔
4802

4803

4804
void msmCheckTasksStatus(SMnode *pMnode) {
377✔
4805
  mstDebug("start to check tasks status, currTs:%" PRId64, mStreamMgmt.hCtx.currentTs);
377✔
4806

4807
  msmCheckVgroupStatus(pMnode);
377✔
4808
  msmCheckSnodeStatus(pMnode);
377✔
4809
}
377✔
4810

4811
void msmCheckSnodesState(SMnode *pMnode) {
377✔
4812
  if (!MST_READY_FOR_SNODE_LOOP()) {
377!
4813
    return;
316✔
4814
  }
4815

4816
  mstDebug("ready to check snode loop, lastTs:%" PRId64, mStreamMgmt.lastTs[STM_EVENT_LOOP_SNODE].ts);
61✔
4817

4818
  void* pIter = NULL;
61✔
4819
  int32_t snodeId = 0;
61✔
4820
  while (true) {
80✔
4821
    pIter = taosHashIterate(mStreamMgmt.snodeMap, pIter);
141✔
4822
    if (NULL == pIter) {
141✔
4823
      break;
61✔
4824
    }
4825

4826
    snodeId = *(int32_t*)taosHashGetKey(pIter, NULL);
80✔
4827
    if (sdbCheckExists(pMnode->pSdb, SDB_SNODE, &snodeId)) {
80✔
4828
      continue;
77✔
4829
    }
4830

4831
    SStmSnodeStatus* pSnode = (SStmSnodeStatus*)pIter;
3✔
4832
    if (NULL == pSnode->streamTasks) {
3✔
4833
      mstDebug("snode %d already cleanup, try to rm it", snodeId);
1!
4834
      taosHashRemove(mStreamMgmt.snodeMap, &snodeId, sizeof(snodeId));
1✔
4835
      continue;
1✔
4836
    }
4837
    
4838
    mstWarn("snode %d lost while streams remain, will redeploy all and rm it, lastUpTs:%" PRId64 ", runnerThreadNum:%d, streamNum:%d", 
2!
4839
        snodeId, pSnode->lastUpTs, pSnode->runnerThreadNum, (int32_t)taosHashGetSize(pSnode->streamTasks));
4840
    
4841
    msmHandleSnodeLost(pMnode, pSnode);
2✔
4842
  }
4843

4844
  MND_STREAM_SET_LAST_TS(STM_EVENT_LOOP_MAP, mStreamMgmt.hCtx.currentTs);
61✔
4845
}
4846

4847
void msmHealthCheck(SMnode *pMnode) {
24,568✔
4848
  int8_t active = atomic_load_8(&mStreamMgmt.active), state = atomic_load_8(&mStreamMgmt.state);
24,568✔
4849
  if (0 == active || MND_STM_STATE_NORMAL != state) {
24,568!
UNCOV
4850
    mstTrace("ignore health check since active:%d state:%d", active, state);
×
UNCOV
4851
    return;
×
4852
  }
4853

4854
  if (sdbGetSize(pMnode->pSdb, SDB_STREAM) <= 0) {
24,568✔
4855
    mstTrace("ignore health check since no stream now");
24,191✔
4856
    return;
24,191✔
4857
  }
4858
  
4859
  mStreamMgmt.hCtx.slotIdx = (mStreamMgmt.hCtx.slotIdx + 1) % MND_STREAM_ISOLATION_PERIOD_NUM;
377✔
4860
  mStreamMgmt.hCtx.currentTs = taosGetTimestampMs();
377✔
4861

4862
  mstDebug("start health check, soltIdx:%d, checkStartTs:%" PRId64, mStreamMgmt.hCtx.slotIdx, mStreamMgmt.hCtx.currentTs);
377✔
4863

4864
  mstWaitLock(&mStreamMgmt.runtimeLock, false);
377✔
4865
  
4866
  msmCheckStreamsStatus(pMnode);
377✔
4867
  msmCheckTasksStatus(pMnode);
377✔
4868
  msmCheckSnodesState(pMnode);
377✔
4869

4870
  taosWUnLockLatch(&mStreamMgmt.runtimeLock);
377✔
4871

4872
  mstDebug("end health check, soltIdx:%d, checkStartTs:%" PRId64, mStreamMgmt.hCtx.slotIdx, mStreamMgmt.hCtx.currentTs);
377✔
4873
}
4874

UNCOV
4875
static bool msmUpdateProfileStreams(SMnode *pMnode, void *pObj, void *p1, void *p2, void *p3) {
×
UNCOV
4876
  SStreamObj *pStream = pObj;
×
UNCOV
4877
  if (atomic_load_8(&pStream->userDropped) || atomic_load_8(&pStream->userStopped)) {
×
UNCOV
4878
    return true;
×
4879
  }
4880
  
UNCOV
4881
  pStream->updateTime = *(int64_t*)p1;
×
4882
  
UNCOV
4883
  (*(int32_t*)p2)++;
×
4884
  
4885
  return true;
×
4886
}
4887

UNCOV
4888
int32_t msmGetTriggerTaskAddr(SMnode *pMnode, int64_t streamId, SStreamTaskAddr* pAddr) {
×
UNCOV
4889
  int32_t code = 0;
×
UNCOV
4890
  int8_t  stopped = 0;
×
4891
  
4892
  mstWaitLock(&mStreamMgmt.runtimeLock, true);
×
4893
  
4894
  SStmStatus* pStatus = (SStmStatus*)taosHashGet(mStreamMgmt.streamMap, &streamId, sizeof(streamId));
×
UNCOV
4895
  if (NULL == pStatus) {
×
UNCOV
4896
    mstsError("stream not exists in streamMap, streamRemains:%d", taosHashGetSize(mStreamMgmt.streamMap));
×
UNCOV
4897
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
UNCOV
4898
    goto _exit;
×
4899
  }
4900

UNCOV
4901
  stopped = atomic_load_8(&pStatus->stopped);
×
4902
  if (stopped) {
×
4903
    mstsError("stream already stopped, stopped:%d", stopped);
×
4904
    code = TSDB_CODE_MND_STREAM_NOT_RUNNING;
×
UNCOV
4905
    goto _exit;
×
4906
  }
4907

UNCOV
4908
  if (pStatus->triggerTask && STREAM_STATUS_RUNNING == pStatus->triggerTask->status) {
×
UNCOV
4909
    pAddr->taskId = pStatus->triggerTask->id.taskId;
×
4910
    pAddr->nodeId = pStatus->triggerTask->id.nodeId;
×
4911
    pAddr->epset = mndGetDnodeEpsetById(pMnode, pAddr->nodeId);
×
4912
    mstsDebug("stream trigger task %" PRIx64 " got with nodeId %d", pAddr->taskId, pAddr->nodeId);
×
UNCOV
4913
    goto _exit;
×
4914
  }
4915

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

4919
_exit:
×
4920
  
UNCOV
4921
  taosRUnLockLatch(&mStreamMgmt.runtimeLock);
×
4922

UNCOV
4923
  return code;
×
4924
}
4925

4926
int32_t msmInitRuntimeInfo(SMnode *pMnode) {
2,407✔
4927
  int32_t code = TSDB_CODE_SUCCESS;
2,407✔
4928
  int32_t lino = 0;
2,407✔
4929
  int32_t vnodeNum = sdbGetSize(pMnode->pSdb, SDB_VGROUP);
2,407✔
4930
  int32_t snodeNum = sdbGetSize(pMnode->pSdb, SDB_SNODE);
2,407✔
4931
  int32_t dnodeNum = sdbGetSize(pMnode->pSdb, SDB_DNODE);
2,407✔
4932

4933
  MND_STREAM_SET_LAST_TS(STM_EVENT_ACTIVE_BEGIN, taosGetTimestampMs());
4,786✔
4934

4935
  mStreamMgmt.stat.activeTimes++;
2,407✔
4936
  mStreamMgmt.threadNum = tsNumOfMnodeStreamMgmtThreads;
2,407✔
4937
  mStreamMgmt.tCtx = taosMemoryCalloc(mStreamMgmt.threadNum, sizeof(SStmThreadCtx));
2,407!
4938
  if (NULL == mStreamMgmt.tCtx) {
2,407!
UNCOV
4939
    code = terrno;
×
4940
    mstError("failed to initialize the stream runtime tCtx, threadNum:%d, error:%s", mStreamMgmt.threadNum, tstrerror(code));
×
4941
    goto _exit;
×
4942
  }
4943

4944
  mStreamMgmt.actionQ = taosMemoryCalloc(1, sizeof(SStmActionQ));
2,407!
4945
  if (mStreamMgmt.actionQ == NULL) {
2,407!
UNCOV
4946
    code = terrno;
×
UNCOV
4947
    mError("failed to initialize the stream runtime actionQ, error:%s", tstrerror(code));
×
4948
    goto _exit;
×
4949
  }
4950
  
4951
  mStreamMgmt.actionQ->head = taosMemoryCalloc(1, sizeof(SStmQNode));
2,407!
4952
  TSDB_CHECK_NULL(mStreamMgmt.actionQ->head, code, lino, _exit, terrno);
2,407!
4953
  
4954
  mStreamMgmt.actionQ->tail = mStreamMgmt.actionQ->head;
2,407✔
4955
  
4956
  for (int32_t i = 0; i < mStreamMgmt.threadNum; ++i) {
14,418✔
4957
    SStmThreadCtx* pCtx = mStreamMgmt.tCtx + i;
12,011✔
4958

4959
    for (int32_t m = 0; m < STREAM_MAX_GROUP_NUM; ++m) {
72,066✔
4960
      pCtx->deployStm[m] = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
60,055✔
4961
      if (pCtx->deployStm[m] == NULL) {
60,055!
UNCOV
4962
        code = terrno;
×
UNCOV
4963
        mError("failed to initialize the stream runtime deployStm[%d][%d], error:%s", i, m, tstrerror(code));
×
UNCOV
4964
        goto _exit;
×
4965
      }
4966
      taosHashSetFreeFp(pCtx->deployStm[m], tDeepFreeSStmStreamDeploy);
60,055✔
4967
      
4968
      pCtx->actionStm[m] = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
60,055✔
4969
      if (pCtx->actionStm[m] == NULL) {
60,055!
UNCOV
4970
        code = terrno;
×
UNCOV
4971
        mError("failed to initialize the stream runtime actionStm[%d][%d], error:%s", i, m, tstrerror(code));
×
UNCOV
4972
        goto _exit;
×
4973
      }
4974
      taosHashSetFreeFp(pCtx->actionStm[m], mstDestroySStmAction);
60,055✔
4975
    }
4976
  }
4977
  
4978
  mStreamMgmt.streamMap = taosHashInit(MND_STREAM_DEFAULT_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
2,407✔
4979
  if (mStreamMgmt.streamMap == NULL) {
2,407!
UNCOV
4980
    code = terrno;
×
UNCOV
4981
    mError("failed to initialize the stream runtime streamMap, error:%s", tstrerror(code));
×
UNCOV
4982
    goto _exit;
×
4983
  }
4984
  taosHashSetFreeFp(mStreamMgmt.streamMap, mstDestroySStmStatus);
2,407✔
4985
  
4986
  mStreamMgmt.taskMap = taosHashInit(MND_STREAM_DEFAULT_TASK_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
2,407✔
4987
  if (mStreamMgmt.taskMap == NULL) {
2,407!
UNCOV
4988
    code = terrno;
×
UNCOV
4989
    mError("failed to initialize the stream runtime taskMap, error:%s", tstrerror(code));
×
UNCOV
4990
    goto _exit;
×
4991
  }
4992
  
4993
  mStreamMgmt.vgroupMap = taosHashInit(vnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
2,407✔
4994
  if (mStreamMgmt.vgroupMap == NULL) {
2,407!
UNCOV
4995
    code = terrno;
×
UNCOV
4996
    mError("failed to initialize the stream runtime vgroupMap, error:%s", tstrerror(code));
×
UNCOV
4997
    goto _exit;
×
4998
  }
4999
  taosHashSetFreeFp(mStreamMgmt.vgroupMap, mstDestroySStmVgroupStatus);
2,407✔
5000

5001
  mStreamMgmt.snodeMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
2,407✔
5002
  if (mStreamMgmt.snodeMap == NULL) {
2,407!
UNCOV
5003
    code = terrno;
×
UNCOV
5004
    mError("failed to initialize the stream runtime snodeMap, error:%s", tstrerror(code));
×
UNCOV
5005
    goto _exit;
×
5006
  }
5007
  taosHashSetFreeFp(mStreamMgmt.snodeMap, mstDestroySStmSnodeStatus);
2,407✔
5008
  
5009
  mStreamMgmt.dnodeMap = taosHashInit(dnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
2,407✔
5010
  if (mStreamMgmt.dnodeMap == NULL) {
2,407!
UNCOV
5011
    code = terrno;
×
UNCOV
5012
    mError("failed to initialize the stream runtime dnodeMap, error:%s", tstrerror(code));
×
UNCOV
5013
    goto _exit;
×
5014
  }
5015

5016
  mStreamMgmt.toDeployVgMap = taosHashInit(vnodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
2,407✔
5017
  if (mStreamMgmt.toDeployVgMap == NULL) {
2,407!
UNCOV
5018
    code = terrno;
×
UNCOV
5019
    mError("failed to initialize the stream runtime toDeployVgMap, error:%s", tstrerror(code));
×
UNCOV
5020
    goto _exit;
×
5021
  }
5022
  taosHashSetFreeFp(mStreamMgmt.toDeployVgMap, mstDestroySStmVgTasksToDeploy);
2,407✔
5023
  
5024
  mStreamMgmt.toDeploySnodeMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
2,407✔
5025
  if (mStreamMgmt.toDeploySnodeMap == NULL) {
2,407!
UNCOV
5026
    code = terrno;
×
UNCOV
5027
    mError("failed to initialize the stream runtime toDeploySnodeMap, error:%s", tstrerror(code));
×
UNCOV
5028
    goto _exit;
×
5029
  }
5030
  taosHashSetFreeFp(mStreamMgmt.toDeploySnodeMap, mstDestroySStmSnodeTasksDeploy);
2,407✔
5031

5032
  mStreamMgmt.toUpdateScanMap = taosHashInit(snodeNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
2,407✔
5033
  if (mStreamMgmt.toUpdateScanMap == NULL) {
2,407!
UNCOV
5034
    code = terrno;
×
UNCOV
5035
    mError("failed to initialize the stream runtime toUpdateScanMap, error:%s", tstrerror(code));
×
UNCOV
5036
    goto _exit;
×
5037
  }
5038
  taosHashSetFreeFp(mStreamMgmt.toUpdateScanMap, mstDestroyScanAddrList);
2,407✔
5039

5040
  TAOS_CHECK_EXIT(msmSTAddSnodesToMap(pMnode));
2,407!
5041
  TAOS_CHECK_EXIT(msmSTAddDnodesToMap(pMnode));
2,407!
5042

5043
  mStreamMgmt.lastTaskId = 1;
2,407✔
5044

5045
  int32_t activeStreamNum = 0;
2,407✔
5046
  sdbTraverse(pMnode->pSdb, SDB_STREAM, msmUpdateProfileStreams, &MND_STREAM_GET_LAST_TS(STM_EVENT_ACTIVE_BEGIN), &activeStreamNum, NULL);
2,407✔
5047

5048
  if (activeStreamNum > 0) {
2,407!
UNCOV
5049
    msmSetInitRuntimeState(MND_STM_STATE_WATCH);
×
5050
  } else {
5051
    msmSetInitRuntimeState(MND_STM_STATE_NORMAL);
2,407✔
5052
  }
5053

5054
_exit:
2,407✔
5055

5056
  if (code) {
2,407!
UNCOV
5057
    msmDestroyRuntimeInfo(pMnode);
×
UNCOV
5058
    mstError("%s failed at line %d since %s", __FUNCTION__, lino, tstrerror(code));
×
5059
  } else {
5060
    mstInfo("mnode stream runtime init done");
2,407!
5061
  }
5062

5063
  return code;
2,407✔
5064
}
5065

5066

5067

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc