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

taosdata / TDengine / #3534

21 Nov 2024 07:36AM UTC coverage: 60.825% (+2.0%) from 58.848%
#3534

push

travis-ci

web-flow
Merge pull request #28810 from taosdata/ehn/add-sync-heartbeat-sent-time-to-log

ehn:add-sync-heartbeat-sent-time-to-log

120023 of 252376 branches covered (47.56%)

Branch coverage included in aggregate %.

43 of 47 new or added lines in 3 files covered. (91.49%)

2254 existing lines in 162 files now uncovered.

200876 of 275203 relevant lines covered (72.99%)

16110754.39 hits per line

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

66.04
/source/client/src/clientMsgHandler.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 "catalog.h"
17
#include "clientInt.h"
18
#include "clientMonitor.h"
19
#include "clientLog.h"
20
#include "cmdnodes.h"
21
#include "os.h"
22
#include "query.h"
23
#include "systable.h"
24
#include "tdatablock.h"
25
#include "tdef.h"
26
#include "tglobal.h"
27
#include "tname.h"
28
#include "tversion.h"
29
#include "command.h"
30

31
extern SClientHbMgr clientHbMgr;
32

33
static void setErrno(SRequestObj* pRequest, int32_t code) {
11,646✔
34
  pRequest->code = code;
11,646✔
35
  terrno = code;
11,646✔
36
}
11,646✔
37

38
int32_t genericRspCallback(void* param, SDataBuf* pMsg, int32_t code) {
9,220✔
39
  SRequestObj* pRequest = param;
9,220✔
40
  setErrno(pRequest, code);
9,220✔
41

42
  if (NEED_CLIENT_RM_TBLMETA_REQ(pRequest->type)) {
9,220!
43
    if (removeMeta(pRequest->pTscObj, pRequest->targetTableList, IS_VIEW_REQUEST(pRequest->type)) != 0){
2,418!
44
      tscError("failed to remove meta data for table");
×
45
    }
46
  }
47

48
  taosMemoryFree(pMsg->pEpSet);
9,220✔
49
  taosMemoryFree(pMsg->pData);
9,220✔
50
  if (pRequest->body.queryFp != NULL) {
9,220✔
51
    doRequestCallback(pRequest, code);
9,214✔
52
  } else {
53
    if (tsem_post(&pRequest->body.rspSem) != 0){
6!
54
      tscError("failed to post semaphore");
×
55
    }
56
  }
57
  return code;
9,220✔
58
}
59

60
int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
12,062✔
61
  SRequestObj* pRequest = acquireRequest(*(int64_t*)param);
12,062✔
62
  if (NULL == pRequest) {
12,063!
63
    goto EXIT;
×
64
  }
65

66
  if (code != TSDB_CODE_SUCCESS) {
12,063✔
67
    goto End;
121✔
68
  }
69

70
  STscObj* pTscObj = pRequest->pTscObj;
11,942✔
71

72
  if (NULL == pTscObj->pAppInfo) {
11,942!
73
    code = TSDB_CODE_TSC_DISCONNECTED;
×
74
    goto End;
×
75
  }
76

77
  SConnectRsp connectRsp = {0};
11,942✔
78
  if (tDeserializeSConnectRsp(pMsg->pData, pMsg->len, &connectRsp) != 0) {
11,942!
79
    code = TSDB_CODE_TSC_INVALID_VERSION;
×
80
    goto End;
×
81
  }
82

83
  if ((code = taosCheckVersionCompatibleFromStr(td_version, connectRsp.sVer, 3)) != 0) {
11,942!
84
    tscError("version not compatible. client version: %s, server version: %s", td_version, connectRsp.sVer);
×
85
    goto End;
×
86
  }
87

88
  int32_t now = taosGetTimestampSec();
11,942✔
89
  int32_t delta = abs(now - connectRsp.svrTimestamp);
11,942✔
90
  if (delta > timestampDeltaLimit) {
11,942!
91
    code = TSDB_CODE_TIME_UNSYNCED;
×
92
    tscError("time diff:%ds is too big", delta);
×
93
    goto End;
×
94
  }
95

96
  if (connectRsp.epSet.numOfEps == 0) {
11,942!
97
    code = TSDB_CODE_APP_ERROR;
×
98
    goto End;
×
99
  }
100

101
  int updateEpSet = 1;
11,942✔
102
  if (connectRsp.dnodeNum == 1) {
11,942✔
103
    SEpSet srcEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
9,306✔
104
    SEpSet dstEpSet = connectRsp.epSet;
9,306✔
105
    if (srcEpSet.numOfEps == 1) {
9,306✔
106
      if (rpcSetDefaultAddr(pTscObj->pAppInfo->pTransporter, srcEpSet.eps[srcEpSet.inUse].fqdn,
7,004!
107
                        dstEpSet.eps[dstEpSet.inUse].fqdn) != 0){
7,004✔
108
        tscError("failed to set default addr for rpc");
×
109
      }
110
      updateEpSet = 0;
7,004✔
111
    }
112
  }
113
  if (updateEpSet == 1 && !isEpsetEqual(&pTscObj->pAppInfo->mgmtEp.epSet, &connectRsp.epSet)) {
11,942✔
114
    SEpSet corEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
2,482✔
115

116
    SEpSet* pOrig = &corEpSet;
2,482✔
117
    SEp*    pOrigEp = &pOrig->eps[pOrig->inUse];
2,482✔
118
    SEp*    pNewEp = &connectRsp.epSet.eps[connectRsp.epSet.inUse];
2,482✔
119
    tscDebug("mnode epset updated from %d/%d=>%s:%d to %d/%d=>%s:%d in connRsp", pOrig->inUse, pOrig->numOfEps,
2,482✔
120
             pOrigEp->fqdn, pOrigEp->port, connectRsp.epSet.inUse, connectRsp.epSet.numOfEps, pNewEp->fqdn,
121
             pNewEp->port);
122
    updateEpSet_s(&pTscObj->pAppInfo->mgmtEp, &connectRsp.epSet);
2,482✔
123
  }
124

125
  for (int32_t i = 0; i < connectRsp.epSet.numOfEps; ++i) {
24,250✔
126
    tscDebug("0x%" PRIx64 " epSet.fqdn[%d]:%s port:%d, connObj:0x%" PRIx64, pRequest->requestId, i,
12,308✔
127
             connectRsp.epSet.eps[i].fqdn, connectRsp.epSet.eps[i].port, pTscObj->id);
128
  }
129

130
  pTscObj->sysInfo = connectRsp.sysInfo;
11,942✔
131
  pTscObj->connId = connectRsp.connId;
11,942✔
132
  pTscObj->acctId = connectRsp.acctId;
11,942✔
133
  tstrncpy(pTscObj->sVer, connectRsp.sVer, tListLen(pTscObj->sVer));
11,942✔
134
  tstrncpy(pTscObj->sDetailVer, connectRsp.sDetailVer, tListLen(pTscObj->sDetailVer));
11,942✔
135

136
  // update the appInstInfo
137
  pTscObj->pAppInfo->clusterId = connectRsp.clusterId;
11,942✔
138
  pTscObj->pAppInfo->serverCfg.monitorParas = connectRsp.monitorParas;
11,942✔
139
  pTscObj->pAppInfo->serverCfg.enableAuditDelete = connectRsp.enableAuditDelete;
11,942✔
140
  tscDebug("[monitor] paras from connect rsp, clusterId:%" PRIx64 " monitorParas threshold:%d scope:%d",
11,942✔
141
           connectRsp.clusterId, connectRsp.monitorParas.tsSlowLogThreshold, connectRsp.monitorParas.tsSlowLogScope);
142
  lastClusterId = connectRsp.clusterId;
11,942✔
143

144
  pTscObj->connType = connectRsp.connType;
11,942✔
145
  pTscObj->passInfo.ver = connectRsp.passVer;
11,942✔
146
  pTscObj->authVer = connectRsp.authVer;
11,942✔
147
  pTscObj->whiteListInfo.ver = connectRsp.whiteListVer;
11,942✔
148

149
  if(taosHashGet(appInfo.pInstMapByClusterId, &connectRsp.clusterId, LONG_BYTES) == NULL){
11,942✔
150
    if(taosHashPut(appInfo.pInstMapByClusterId, &connectRsp.clusterId, LONG_BYTES, &pTscObj->pAppInfo, POINTER_BYTES) != 0){
4,030!
151
      tscError("failed to put appInfo into appInfo.pInstMapByClusterId");
×
152
    }else{
153
      MonitorSlowLogData data = {0};
4,030✔
154
      data.clusterId = pTscObj->pAppInfo->clusterId;
4,030✔
155
      data.type = SLOW_LOG_READ_BEGINNIG;
4,030✔
156
      (void)monitorPutData2MonitorQueue(data); // ignore
4,030✔
157
      monitorClientSlowQueryInit(connectRsp.clusterId);
4,030✔
158
      monitorClientSQLReqInit(connectRsp.clusterId);
4,030✔
159
    }
160
  }
161

162
  (void)taosThreadMutexLock(&clientHbMgr.lock);
11,942✔
163
  SAppHbMgr* pAppHbMgr = taosArrayGetP(clientHbMgr.appHbMgrs, pTscObj->appHbMgrIdx);
11,942✔
164
  if (pAppHbMgr) {
11,942!
165
    if (hbRegisterConn(pAppHbMgr, pTscObj->id, connectRsp.clusterId, connectRsp.connType) != 0){
11,942!
166
      tscError("0x%" PRIx64 " failed to register conn to hbMgr", pRequest->requestId);
×
167
    }
168
  } else {
169
    (void)taosThreadMutexUnlock(&clientHbMgr.lock);
×
170
    code = TSDB_CODE_TSC_DISCONNECTED;
×
171
    goto End;
×
172
  }
173
  (void)taosThreadMutexUnlock(&clientHbMgr.lock);
11,942✔
174

175
  tscDebug("0x%" PRIx64 " clusterId:%" PRId64 ", totalConn:%" PRId64, pRequest->requestId, connectRsp.clusterId,
11,942✔
176
           pTscObj->pAppInfo->numOfConns);
177

178
End:
10,628✔
179
  if (code != 0){
12,063✔
180
    setErrno(pRequest, code);
121✔
181
  }
182
  if (tsem_post(&pRequest->body.rspSem) != 0){
12,063!
183
    tscError("failed to post semaphore");
×
184
  }
185

186
  if (pRequest) {
12,063!
187
    (void)releaseRequest(pRequest->self);
12,063✔
188
  }
189

190
EXIT:
×
191
  taosMemoryFree(param);
12,063✔
192
  taosMemoryFree(pMsg->pEpSet);
12,063✔
193
  taosMemoryFree(pMsg->pData);
12,063✔
194
  return code;
12,063✔
195
}
196

197
SMsgSendInfo* buildMsgInfoImpl(SRequestObj* pRequest) {
38,176✔
198
  SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
38,176✔
199
  if(pMsgSendInfo == NULL) return pMsgSendInfo;
38,178!
200
  pMsgSendInfo->requestObjRefId = pRequest->self;
38,178✔
201
  pMsgSendInfo->requestId = pRequest->requestId;
38,178✔
202
  pMsgSendInfo->param = pRequest;
38,178✔
203
  pMsgSendInfo->msgType = pRequest->type;
38,178✔
204
  pMsgSendInfo->target.type = TARGET_TYPE_MNODE;
38,178✔
205

206
  pMsgSendInfo->msgInfo = pRequest->body.requestMsg;
38,178✔
207
  pMsgSendInfo->fp = getMsgRspHandle(pRequest->type);
38,178✔
208
  return pMsgSendInfo;
38,178✔
209
}
210

211
int32_t processCreateDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
4,869✔
212
  // todo rsp with the vnode id list
213
  SRequestObj* pRequest = param;
4,869✔
214
  taosMemoryFree(pMsg->pData);
4,869✔
215
  taosMemoryFree(pMsg->pEpSet);
4,869✔
216
  if (code != TSDB_CODE_SUCCESS) {
4,869✔
217
    setErrno(pRequest, code);
525✔
218
  } else {
219
    struct SCatalog* pCatalog = NULL;
4,344✔
220
    code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
4,344✔
221
    if (TSDB_CODE_SUCCESS == code) {
4,344!
222
      STscObj* pTscObj = pRequest->pTscObj;
4,344✔
223

224
      SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
4,344✔
225
                               .requestId = pRequest->requestId,
4,344✔
226
                               .requestObjRefId = pRequest->self,
4,344✔
227
                               .mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
4,344✔
228
      char             dbFName[TSDB_DB_FNAME_LEN];
229
      (void)snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_INFORMATION_SCHEMA_DB);
4,344✔
230
      if (catalogRefreshDBVgInfo(pCatalog, &conn, dbFName) != 0){
4,344!
231
        tscError("0x%" PRIx64 " failed to refresh db vg info", pRequest->requestId);
×
232
      }
233
      (void)snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_PERFORMANCE_SCHEMA_DB);
4,344✔
234
      if (catalogRefreshDBVgInfo(pCatalog, &conn, dbFName) != 0){
4,344!
UNCOV
235
        tscError("0x%" PRIx64 " failed to refresh db vg info", pRequest->requestId);
×
236
      }
237
    }
238
  }
239

240
  if (pRequest->body.queryFp) {
4,869!
241
    doRequestCallback(pRequest, code);
4,869✔
242
  } else {
243
    if (tsem_post(&pRequest->body.rspSem) != 0){
×
244
      tscError("failed to post semaphore");
×
245
    }
246
  }
247
  return code;
4,869✔
248
}
249

250
int32_t processUseDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
9,394✔
251
  SRequestObj* pRequest = param;
9,394✔
252
  if (TSDB_CODE_MND_DB_NOT_EXIST == code || TSDB_CODE_MND_DB_IN_CREATING == code ||
9,394!
253
      TSDB_CODE_MND_DB_IN_DROPPING == code) {
254
    SUseDbRsp usedbRsp = {0};
1✔
255
    if (tDeserializeSUseDbRsp(pMsg->pData, pMsg->len, &usedbRsp) != 0){
1!
256
      tscError("0x%" PRIx64 " deserialize SUseDbRsp failed", pRequest->requestId);
1!
257
    }
258
    struct SCatalog* pCatalog = NULL;
1✔
259

260
    if (usedbRsp.vgVersion >= 0) {  // cached in local
1!
261
      int64_t clusterId = pRequest->pTscObj->pAppInfo->clusterId;
1✔
262
      int32_t  code1 = catalogGetHandle(clusterId, &pCatalog);
1✔
263
      if (code1 != TSDB_CODE_SUCCESS) {
1!
264
        tscWarn("0x%" PRIx64 "catalogGetHandle failed, clusterId:%" PRIx64 ", error:%s", pRequest->requestId, clusterId,
×
265
                tstrerror(code1));
266
      } else {
267
        if (catalogRemoveDB(pCatalog, usedbRsp.db, usedbRsp.uid) != 0){
1!
268
          tscError("0x%" PRIx64 "catalogRemoveDB failed, db:%s, uid:%" PRId64, pRequest->requestId, usedbRsp.db,
×
269
                   usedbRsp.uid);
270
        }
271
      }
272
    }
273
    tFreeSUsedbRsp(&usedbRsp);
1✔
274
  }
275

276
  if (code != TSDB_CODE_SUCCESS) {
9,394✔
277
    taosMemoryFree(pMsg->pData);
8✔
278
    taosMemoryFree(pMsg->pEpSet);
8✔
279
    setErrno(pRequest, code);
8✔
280

281
    if (pRequest->body.queryFp != NULL) {
8!
282
      doRequestCallback(pRequest, pRequest->code);
8✔
283

284
    } else {
285
      if (tsem_post(&pRequest->body.rspSem) != 0){
×
286
        tscError("failed to post semaphore");
×
287
      }
288
    }
289

290
    return code;
8✔
291
  }
292

293
  SUseDbRsp usedbRsp = {0};
9,386✔
294
  if (tDeserializeSUseDbRsp(pMsg->pData, pMsg->len, &usedbRsp) != 0){
9,386!
295
    tscError("0x%" PRIx64 " deserialize SUseDbRsp failed", pRequest->requestId);
×
296
  }
297

298
  if (strlen(usedbRsp.db) == 0) {
9,385!
299
    taosMemoryFree(pMsg->pData);
×
300
    taosMemoryFree(pMsg->pEpSet);
×
301

302
    if (usedbRsp.errCode != 0) {
×
303
      return usedbRsp.errCode;
×
304
    } else {
305
      return TSDB_CODE_APP_ERROR;
×
306
    }
307
  }
308

309
  tscTrace("db:%s, usedbRsp received, numOfVgroups:%d", usedbRsp.db, usedbRsp.vgNum);
9,385✔
310
  for (int32_t i = 0; i < usedbRsp.vgNum; ++i) {
16,566✔
311
    SVgroupInfo* pInfo = taosArrayGet(usedbRsp.pVgroupInfos, i);
7,181✔
312
    if (pInfo == NULL){
7,181!
313
      continue;
×
314
    }
315
    tscTrace("vgId:%d, numOfEps:%d inUse:%d ", pInfo->vgId, pInfo->epSet.numOfEps, pInfo->epSet.inUse);
7,181✔
316
    for (int32_t j = 0; j < pInfo->epSet.numOfEps; ++j) {
14,814✔
317
      tscTrace("vgId:%d, index:%d epset:%s:%u", pInfo->vgId, j, pInfo->epSet.eps[j].fqdn, pInfo->epSet.eps[j].port);
7,633✔
318
    }
319
  }
320

321
  SName name = {0};
9,385✔
322
  if(tNameFromString(&name, usedbRsp.db, T_NAME_ACCT | T_NAME_DB) != TSDB_CODE_SUCCESS) {
9,385!
323
    tscError("0x%" PRIx64 " failed to parse db name:%s", pRequest->requestId, usedbRsp.db);
×
324
  }
325

326
  SUseDbOutput output = {0};
9,384✔
327
  code = queryBuildUseDbOutput(&output, &usedbRsp);
9,384✔
328
  if (code != 0) {
9,386!
329
    terrno = code;
×
330
    if (output.dbVgroup) taosHashCleanup(output.dbVgroup->vgHash);
×
331

332
    tscError("0x%" PRIx64 " failed to build use db output since %s", pRequest->requestId, terrstr());
×
333
  } else if (output.dbVgroup && output.dbVgroup->vgHash) {
9,386!
334
    struct SCatalog* pCatalog = NULL;
3,206✔
335

336
    int32_t code1 = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
3,206✔
337
    if (code1 != TSDB_CODE_SUCCESS) {
3,206!
338
      tscWarn("catalogGetHandle failed, clusterId:%" PRIx64 ", error:%s", pRequest->pTscObj->pAppInfo->clusterId,
×
339
              tstrerror(code1));
340
    } else {
341
      if (catalogUpdateDBVgInfo(pCatalog, output.db, output.dbId, output.dbVgroup) != 0){
3,206!
342
        tscError("0x%" PRIx64 " failed to update db vg info, db:%s, dbId:%" PRId64, pRequest->requestId, output.db,
×
343
                 output.dbId);
344
      }
345
      output.dbVgroup = NULL;
3,206✔
346
    }
347
  }
348

349
  taosMemoryFreeClear(output.dbVgroup);
9,386✔
350
  tFreeSUsedbRsp(&usedbRsp);
9,385✔
351

352
  char db[TSDB_DB_NAME_LEN] = {0};
9,386✔
353
  if(tNameGetDbName(&name, db) != TSDB_CODE_SUCCESS) {
9,386!
354
    tscError("0x%" PRIx64 " failed to get db name since %s", pRequest->requestId, tstrerror(code));
×
355
  }
356

357
  setConnectionDB(pRequest->pTscObj, db);
9,386✔
358

359
  taosMemoryFree(pMsg->pData);
9,386✔
360
  taosMemoryFree(pMsg->pEpSet);
9,386✔
361

362
  if (pRequest->body.queryFp != NULL) {
9,385!
363
    doRequestCallback(pRequest, pRequest->code);
9,385✔
364
  } else {
365
    if (tsem_post(&pRequest->body.rspSem) != 0){
×
366
      tscError("failed to post semaphore");
×
367
    }
368
  }
369
  return 0;
9,386✔
370
}
371

372
int32_t processCreateSTableRsp(void* param, SDataBuf* pMsg, int32_t code) {
7,216✔
373
  if (pMsg == NULL) {
7,216!
374
    return TSDB_CODE_TSC_INVALID_INPUT;
×
375
  }
376
  if (param == NULL) {
7,216!
377
    taosMemoryFree(pMsg->pEpSet);
×
378
    taosMemoryFree(pMsg->pData);
×
379
    return TSDB_CODE_TSC_INVALID_INPUT;
×
380
  }
381

382
  SRequestObj* pRequest = param;
7,216✔
383

384
  if (code != TSDB_CODE_SUCCESS) {
7,216✔
385
    setErrno(pRequest, code);
70✔
386
  } else {
387
    SMCreateStbRsp createRsp = {0};
7,146✔
388
    SDecoder       coder = {0};
7,146✔
389
    tDecoderInit(&coder, pMsg->pData, pMsg->len);
7,146✔
390
    if (pMsg->len > 0){
7,146✔
391
      code = tDecodeSMCreateStbRsp(&coder, &createRsp);  // pMsg->len == 0
7,083✔
392
      if (code != TSDB_CODE_SUCCESS) {
7,083!
393
        setErrno(pRequest, code);
×
394
      }
395
    }
396
    tDecoderClear(&coder);
7,146✔
397

398
    pRequest->body.resInfo.execRes.msgType = TDMT_MND_CREATE_STB;
7,146✔
399
    pRequest->body.resInfo.execRes.res = createRsp.pMeta;
7,146✔
400
  }
401

402
  taosMemoryFree(pMsg->pEpSet);
7,216✔
403
  taosMemoryFree(pMsg->pData);
7,216✔
404

405
  if (pRequest->body.queryFp != NULL) {
7,216✔
406
    SExecResult* pRes = &pRequest->body.resInfo.execRes;
6,283✔
407

408
    if (code == TSDB_CODE_SUCCESS) {
6,283✔
409
      SCatalog* pCatalog = NULL;
6,249✔
410
      int32_t   ret = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
6,249✔
411
      if (pRes->res != NULL) {
6,249✔
412
        ret = handleCreateTbExecRes(pRes->res, pCatalog);
6,243✔
413
      }
414

415
      if (ret != TSDB_CODE_SUCCESS) {
6,249!
416
        code = ret;
×
417
      }
418
    }
419

420
    doRequestCallback(pRequest, code);
6,283✔
421
  } else {
422
    if (tsem_post(&pRequest->body.rspSem) != 0){
933!
423
      tscError("failed to post semaphore");
×
424
    }
425
  }
426
  return code;
7,216✔
427
}
428

429
int32_t processDropDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
3,535✔
430
  SRequestObj* pRequest = param;
3,535✔
431
  if (code != TSDB_CODE_SUCCESS) {
3,535✔
432
    setErrno(pRequest, code);
105✔
433
  } else {
434
    SDropDbRsp dropdbRsp = {0};
3,430✔
435
    if (tDeserializeSDropDbRsp(pMsg->pData, pMsg->len, &dropdbRsp) != 0){
3,430!
436
      tscError("0x%" PRIx64 " deserialize SDropDbRsp failed", pRequest->requestId);
×
437
    }
438
    struct SCatalog* pCatalog = NULL;
3,430✔
439
    code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
3,430✔
440
    if (TSDB_CODE_SUCCESS == code) {
3,430!
441
      if (catalogRemoveDB(pCatalog, dropdbRsp.db, dropdbRsp.uid) != 0){
3,430!
442
        tscError("0x%" PRIx64 " failed to remove db:%s", pRequest->requestId, dropdbRsp.db);
×
443
      }
444
      STscObj* pTscObj = pRequest->pTscObj;
3,430✔
445

446
      SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
3,430✔
447
                               .requestId = pRequest->requestId,
3,430✔
448
                               .requestObjRefId = pRequest->self,
3,430✔
449
                               .mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
3,430✔
450
      char             dbFName[TSDB_DB_FNAME_LEN] = {0};
3,430✔
451
      (void)snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_INFORMATION_SCHEMA_DB);
3,430✔
452
      if (catalogRefreshDBVgInfo(pCatalog, &conn, dbFName) != TSDB_CODE_SUCCESS) {
3,430!
453
        tscError("0x%" PRIx64 " failed to refresh db vg info, db:%s", pRequest->requestId, dbFName);
×
454
       }
455
      (void)snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_PERFORMANCE_SCHEMA_DB);
3,430✔
456
      if (catalogRefreshDBVgInfo(pCatalog, &conn, dbFName) != 0) {
3,430!
457
        tscError("0x%" PRIx64 " failed to refresh db vg info, db:%s", pRequest->requestId, dbFName);
×
458
      }
459
    }
460
  }
461

462
  taosMemoryFree(pMsg->pData);
3,535✔
463
  taosMemoryFree(pMsg->pEpSet);
3,535✔
464

465
  if (pRequest->body.queryFp != NULL) {
3,535!
466
    doRequestCallback(pRequest, code);
3,535✔
467
  } else {
468
    if (tsem_post(&pRequest->body.rspSem) != 0){
×
469
      tscError("failed to post semaphore");
×
470
    }
471
  }
472
  return code;
3,535✔
473
}
474

475
int32_t processAlterStbRsp(void* param, SDataBuf* pMsg, int32_t code) {
3,922✔
476
  SRequestObj* pRequest = param;
3,922✔
477
  if (code != TSDB_CODE_SUCCESS) {
3,922✔
478
    setErrno(pRequest, code);
1,597✔
479
  } else {
480
    SMAlterStbRsp alterRsp = {0};
2,325✔
481
    SDecoder      coder = {0};
2,325✔
482
    tDecoderInit(&coder, pMsg->pData, pMsg->len);
2,325✔
483
    if (pMsg->len > 0){
2,325✔
484
      code = tDecodeSMAlterStbRsp(&coder, &alterRsp);  // pMsg->len == 0
2,296✔
485
      if (code != TSDB_CODE_SUCCESS) {
2,296!
486
        setErrno(pRequest, code);
×
487
      }
488
    }
489
    tDecoderClear(&coder);
2,325✔
490

491
    pRequest->body.resInfo.execRes.msgType = TDMT_MND_ALTER_STB;
2,325✔
492
    pRequest->body.resInfo.execRes.res = alterRsp.pMeta;
2,325✔
493
  }
494

495
  taosMemoryFree(pMsg->pData);
3,922✔
496
  taosMemoryFree(pMsg->pEpSet);
3,922✔
497

498
  if (pRequest->body.queryFp != NULL) {
3,922!
499
    SExecResult* pRes = &pRequest->body.resInfo.execRes;
3,922✔
500

501
    if (code == TSDB_CODE_SUCCESS) {
3,922✔
502
      SCatalog* pCatalog = NULL;
2,325✔
503
      int32_t   ret = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
2,325✔
504
      if (pRes->res != NULL) {
2,325✔
505
        ret = handleAlterTbExecRes(pRes->res, pCatalog);
2,296✔
506
      }
507

508
      if (ret != TSDB_CODE_SUCCESS) {
2,325!
509
        code = ret;
×
510
      }
511
    }
512

513
    doRequestCallback(pRequest, code);
3,922✔
514
  } else {
515
    if (tsem_post(&pRequest->body.rspSem) != 0){
×
516
      tscError("failed to post semaphore");
×
517
    }
518
  }
519
  return code;
3,922✔
520
}
521

522
static int32_t buildShowVariablesBlock(SArray* pVars, SSDataBlock** block) {
11✔
523
  int32_t code = 0;
11✔
524
  int32_t line = 0;
11✔
525
  SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
11✔
526
  TSDB_CHECK_NULL(pBlock, code, line, END, terrno);
11!
527
  pBlock->info.hasVarCol = true;
11✔
528

529
  pBlock->pDataBlock = taosArrayInit(SHOW_VARIABLES_RESULT_COLS, sizeof(SColumnInfoData));
11✔
530
  TSDB_CHECK_NULL(pBlock->pDataBlock, code, line, END, terrno);
11!
531
  SColumnInfoData infoData = {0};
11✔
532
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
11✔
533
  infoData.info.bytes = SHOW_VARIABLES_RESULT_FIELD1_LEN;
11✔
534
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
22!
535

536
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
11✔
537
  infoData.info.bytes = SHOW_VARIABLES_RESULT_FIELD2_LEN;
11✔
538
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
22!
539

540
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
11✔
541
  infoData.info.bytes = SHOW_VARIABLES_RESULT_FIELD3_LEN;
11✔
542
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
22!
543

544
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
11✔
545
  infoData.info.bytes = SHOW_VARIABLES_RESULT_FIELD4_LEN;
11✔
546
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
22!
547

548
  int32_t numOfCfg = taosArrayGetSize(pVars);
11✔
549
  code = blockDataEnsureCapacity(pBlock, numOfCfg);
11✔
550
  TSDB_CHECK_CODE(code, line, END);
11!
551

552
  for (int32_t i = 0, c = 0; i < numOfCfg; ++i, c = 0) {
110✔
553
    SVariablesInfo* pInfo = taosArrayGet(pVars, i);
99✔
554
    TSDB_CHECK_NULL(pInfo, code, line, END, terrno);
99!
555

556
    char name[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0};
99✔
557
    STR_WITH_MAXSIZE_TO_VARSTR(name, pInfo->name, TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE);
99✔
558
    SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
99✔
559
    TSDB_CHECK_NULL(pColInfo, code, line, END, terrno);
99!
560
    code = colDataSetVal(pColInfo, i, name, false);
99✔
561
    TSDB_CHECK_CODE(code, line, END);
99!
562

563
    char value[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0};
99✔
564
    STR_WITH_MAXSIZE_TO_VARSTR(value, pInfo->value, TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE);
99✔
565
    pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
99✔
566
    TSDB_CHECK_NULL(pColInfo, code, line, END, terrno);
99!
567
    code = colDataSetVal(pColInfo, i, value, false);
99✔
568
    TSDB_CHECK_CODE(code, line, END);
99!
569

570
    char scope[TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE] = {0};
99✔
571
    STR_WITH_MAXSIZE_TO_VARSTR(scope, pInfo->scope, TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE);
99✔
572
    pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
99✔
573
    TSDB_CHECK_NULL(pColInfo, code, line, END, terrno);
99!
574
    code = colDataSetVal(pColInfo, i, scope, false);
99✔
575
    TSDB_CHECK_CODE(code, line, END);
99!
576

577
    char info[TSDB_CONFIG_INFO_LEN + VARSTR_HEADER_SIZE] = {0};
99✔
578
    STR_WITH_MAXSIZE_TO_VARSTR(info, pInfo->info, TSDB_CONFIG_INFO_LEN + VARSTR_HEADER_SIZE);
99✔
579
    pColInfo = taosArrayGet(pBlock->pDataBlock, c++);
99✔
580
    TSDB_CHECK_NULL(pColInfo, code, line, END, terrno);
99!
581
    code = colDataSetVal(pColInfo, i, info, false);
99✔
582
    TSDB_CHECK_CODE(code, line, END);
99!
583
  }
584

585
  pBlock->info.rows = numOfCfg;
11✔
586

587
  *block = pBlock;
11✔
588
  return code;
11✔
589

590
END:
×
591
  taosArrayDestroy(pBlock->pDataBlock);
×
592
  taosMemoryFree(pBlock);
×
593
  return code;
×
594
}
595

596
static int32_t buildShowVariablesRsp(SArray* pVars, SRetrieveTableRsp** pRsp) {
11✔
597
  SSDataBlock* pBlock = NULL;
11✔
598
  int32_t      code = buildShowVariablesBlock(pVars, &pBlock);
11✔
599
  if (code) {
11!
600
    return code;
×
601
  }
602

603
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
11✔
604
  size_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
11✔
605
  *pRsp = taosMemoryCalloc(1, rspSize);
11✔
606
  if (NULL == *pRsp) {
11!
607
    code = terrno;
×
608
    goto  _exit;
×
609
  }
610

611
  (*pRsp)->useconds = 0;
11✔
612
  (*pRsp)->completed = 1;
11✔
613
  (*pRsp)->precision = 0;
11✔
614
  (*pRsp)->compressed = 0;
11✔
615

616
  (*pRsp)->numOfRows = htobe64((int64_t)pBlock->info.rows);
11✔
617
  (*pRsp)->numOfCols = htonl(SHOW_VARIABLES_RESULT_COLS);
11✔
618

619
  int32_t len = blockEncode(pBlock, (*pRsp)->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, SHOW_VARIABLES_RESULT_COLS);
11✔
620
  if(len < 0) {
11!
621
    uError("buildShowVariablesRsp error, len:%d", len);
×
622
    code = terrno;
×
623
    goto _exit;
×
624
  }
625
  blockDataDestroy(pBlock);
11✔
626

627
  SET_PAYLOAD_LEN((*pRsp)->data, len, len);
11✔
628

629
  int32_t payloadLen = len + PAYLOAD_PREFIX_LEN;
11✔
630
  (*pRsp)->payloadLen = htonl(payloadLen);
11✔
631
  (*pRsp)->compLen = htonl(payloadLen);
11✔
632

633
  if (payloadLen != rspSize - sizeof(SRetrieveTableRsp)) {
11!
634
    uError("buildShowVariablesRsp error, len:%d != rspSize - sizeof(SRetrieveTableRsp):%" PRIu64, len,
×
635
           (uint64_t)(rspSize - sizeof(SRetrieveTableRsp)));
636
    code = TSDB_CODE_TSC_INVALID_INPUT;
×
637
    goto _exit;
×
638
  }
639

640
  return TSDB_CODE_SUCCESS;
11✔
641
_exit:
×
642
  if(*pRsp)  {
×
643
    taosMemoryFree(*pRsp);
×
644
    *pRsp = NULL;
×
645
  }
646
  if(pBlock) {
×
647
    blockDataDestroy(pBlock);
×
648
    pBlock = NULL;
×
649
  }
650
  return code;
×
651
}
652

653
int32_t processShowVariablesRsp(void* param, SDataBuf* pMsg, int32_t code) {
11✔
654
  SRequestObj* pRequest = param;
11✔
655
  if (code != TSDB_CODE_SUCCESS) {
11!
656
    setErrno(pRequest, code);
×
657
  } else {
658
    SShowVariablesRsp  rsp = {0};
11✔
659
    SRetrieveTableRsp* pRes = NULL;
11✔
660
    code = tDeserializeSShowVariablesRsp(pMsg->pData, pMsg->len, &rsp);
11✔
661
    if (TSDB_CODE_SUCCESS == code) {
11!
662
      code = buildShowVariablesRsp(rsp.variables, &pRes);
11✔
663
    }
664
    if (TSDB_CODE_SUCCESS == code) {
11!
665
      code = setQueryResultFromRsp(&pRequest->body.resInfo, pRes, false);
11✔
666
    }
667

668
    if (code != 0) {
11!
669
      taosMemoryFree(pRes);
×
670
    }
671
    tFreeSShowVariablesRsp(&rsp);
11✔
672
  }
673

674
  taosMemoryFree(pMsg->pData);
11✔
675
  taosMemoryFree(pMsg->pEpSet);
11✔
676

677
  if (pRequest->body.queryFp != NULL) {
11!
678
    doRequestCallback(pRequest, code);
11✔
679
  } else {
680
    if (tsem_post(&pRequest->body.rspSem) != 0){
×
681
      tscError("failed to post semaphore");
×
682
    }
683
  }
684
  return code;
11✔
685
}
686

687
static int32_t buildCompactDbBlock(SCompactDbRsp* pRsp, SSDataBlock** block) {
11✔
688
  int32_t code = 0;
11✔
689
  int32_t line = 0;
11✔
690
  SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
11✔
691
  TSDB_CHECK_NULL(pBlock, code, line, END, terrno);
11!
692
  pBlock->info.hasVarCol = true;
11✔
693

694
  pBlock->pDataBlock = taosArrayInit(COMPACT_DB_RESULT_COLS, sizeof(SColumnInfoData));
11✔
695
  TSDB_CHECK_NULL(pBlock->pDataBlock, code, line, END, terrno);
11!
696
  SColumnInfoData infoData = {0};
11✔
697
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
11✔
698
  infoData.info.bytes = COMPACT_DB_RESULT_FIELD1_LEN;
11✔
699
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
22!
700

701
  infoData.info.type = TSDB_DATA_TYPE_INT;
11✔
702
  infoData.info.bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes;
11✔
703
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
22!
704

705
  infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
11✔
706
  infoData.info.bytes = COMPACT_DB_RESULT_FIELD3_LEN;
11✔
707
  TSDB_CHECK_NULL(taosArrayPush(pBlock->pDataBlock, &infoData), code, line, END, terrno);
22!
708

709
  code = blockDataEnsureCapacity(pBlock, 1);
11✔
710
  TSDB_CHECK_CODE(code, line, END);
11!
711

712
  SColumnInfoData* pResultCol = taosArrayGet(pBlock->pDataBlock, 0);
11✔
713
  TSDB_CHECK_NULL(pResultCol, code, line, END, terrno);
11!
714
  SColumnInfoData* pIdCol = taosArrayGet(pBlock->pDataBlock, 1);
11✔
715
  TSDB_CHECK_NULL(pIdCol, code, line, END, terrno);
11!
716
  SColumnInfoData* pReasonCol = taosArrayGet(pBlock->pDataBlock, 2);
11✔
717
  TSDB_CHECK_NULL(pReasonCol, code, line, END, terrno);
11!
718

719
  char result[COMPACT_DB_RESULT_FIELD1_LEN] = {0};
11✔
720
  char reason[COMPACT_DB_RESULT_FIELD3_LEN] = {0};
11✔
721
  if (pRsp->bAccepted) {
11!
722
    STR_TO_VARSTR(result, "accepted");
11✔
723
    code = colDataSetVal(pResultCol, 0, result, false);
11✔
724
    TSDB_CHECK_CODE(code, line, END);
11!
725
    code = colDataSetVal(pIdCol, 0, (void*)&pRsp->compactId, false);
11✔
726
    TSDB_CHECK_CODE(code, line, END);
11!
727
    STR_TO_VARSTR(reason, "success");
11✔
728
    code = colDataSetVal(pReasonCol, 0, reason, false);
11✔
729
    TSDB_CHECK_CODE(code, line, END);
11!
730
  } else {
731
    STR_TO_VARSTR(result, "rejected");
×
732
    code = colDataSetVal(pResultCol, 0, result, false);
×
733
    TSDB_CHECK_CODE(code, line, END);
×
734
    colDataSetNULL(pIdCol, 0);
735
    STR_TO_VARSTR(reason, "compaction is ongoing");
×
736
    code = colDataSetVal(pReasonCol, 0, reason, false);
×
737
    TSDB_CHECK_CODE(code, line, END);
×
738
  }
739
  pBlock->info.rows = 1;
11✔
740

741
  *block = pBlock;
11✔
742

743
  return TSDB_CODE_SUCCESS;
11✔
744
END:
×
745
  taosMemoryFree(pBlock);
×
746
  taosArrayDestroy(pBlock->pDataBlock);
×
747
  return code;
×
748
}
749

750
static int32_t buildRetriveTableRspForCompactDb(SCompactDbRsp* pCompactDb, SRetrieveTableRsp** pRsp) {
11✔
751
  SSDataBlock* pBlock = NULL;
11✔
752
  int32_t      code = buildCompactDbBlock(pCompactDb, &pBlock);
11✔
753
  if (code) {
11!
754
    return code;
×
755
  }
756

757
  size_t dataEncodeBufSize = blockGetEncodeSize(pBlock);
11✔
758
  size_t rspSize = sizeof(SRetrieveTableRsp) + dataEncodeBufSize + PAYLOAD_PREFIX_LEN;
11✔
759
  *pRsp = taosMemoryCalloc(1, rspSize);
11✔
760
  if (NULL == *pRsp) {
11!
761
    code = terrno;
×
762
    goto _exit;
×
763
  }
764

765
  (*pRsp)->useconds = 0;
11✔
766
  (*pRsp)->completed = 1;
11✔
767
  (*pRsp)->precision = 0;
11✔
768
  (*pRsp)->compressed = 0;
11✔
769
  (*pRsp)->compLen = 0;
11✔
770
  (*pRsp)->payloadLen = 0;
11✔
771
  (*pRsp)->numOfRows = htobe64((int64_t)pBlock->info.rows);
11✔
772
  (*pRsp)->numOfCols = htonl(COMPACT_DB_RESULT_COLS);
11✔
773

774
  int32_t len = blockEncode(pBlock, (*pRsp)->data + PAYLOAD_PREFIX_LEN, dataEncodeBufSize, COMPACT_DB_RESULT_COLS);
11✔
775
  if(len < 0) {
11!
776
    uError("buildRetriveTableRspForCompactDb error, len:%d", len);
×
777
    code = terrno;
×
778
    goto _exit;
×
779
  }
780
  blockDataDestroy(pBlock);
11✔
781

782
  SET_PAYLOAD_LEN((*pRsp)->data, len, len);
11✔
783

784
  int32_t payloadLen = len + PAYLOAD_PREFIX_LEN;
11✔
785
  (*pRsp)->payloadLen = htonl(payloadLen);
11✔
786
  (*pRsp)->compLen = htonl(payloadLen);
11✔
787

788
  if (payloadLen != rspSize - sizeof(SRetrieveTableRsp)) {
11!
789
    uError("buildRetriveTableRspForCompactDb error, len:%d != rspSize - sizeof(SRetrieveTableRsp):%" PRIu64, len,
×
790
           (uint64_t)(rspSize - sizeof(SRetrieveTableRsp)));
791
    code = TSDB_CODE_TSC_INVALID_INPUT;
×
792
    goto _exit;
×
793
  }
794

795
  return TSDB_CODE_SUCCESS;
11✔
796
_exit:
×
797
  if(*pRsp)  {
×
798
    taosMemoryFree(*pRsp);
×
799
    *pRsp = NULL;
×
800
  }
801
  if(pBlock) {
×
802
    blockDataDestroy(pBlock);
×
803
    pBlock = NULL;
×
804
  }
805
  return code;
×
806
}
807

808

809
int32_t processCompactDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
11✔
810
  SRequestObj* pRequest = param;
11✔
811
  if (code != TSDB_CODE_SUCCESS) {
11!
812
    setErrno(pRequest, code);
×
813
  } else {
814
    SCompactDbRsp  rsp = {0};
11✔
815
    SRetrieveTableRsp* pRes = NULL;
11✔
816
    code = tDeserializeSCompactDbRsp(pMsg->pData, pMsg->len, &rsp);
11✔
817
    if (TSDB_CODE_SUCCESS == code) {
11!
818
      code = buildRetriveTableRspForCompactDb(&rsp, &pRes);
11✔
819
    }
820
    if (TSDB_CODE_SUCCESS == code) {
11!
821
      code = setQueryResultFromRsp(&pRequest->body.resInfo, pRes, false);
11✔
822
    }
823

824
    if (code != 0) {
11!
825
      taosMemoryFree(pRes);
×
826
    }
827
  }
828

829
  taosMemoryFree(pMsg->pData);
11✔
830
  taosMemoryFree(pMsg->pEpSet);
11✔
831

832
  if (pRequest->body.queryFp != NULL) {
11!
833
    pRequest->body.queryFp(((SSyncQueryParam *)pRequest->body.interParam)->userParam, pRequest, code);
11✔
834
  } else {
835
    if (tsem_post(&pRequest->body.rspSem) != 0){
×
836
      tscError("failed to post semaphore");
×
837
    }
838
  }
839
  return code;
11✔
840
}
841

842
__async_send_cb_fn_t getMsgRspHandle(int32_t msgType) {
50,240✔
843
  switch (msgType) {
50,240✔
844
    case TDMT_MND_CONNECT:
12,063✔
845
      return processConnectRsp;
12,063✔
846
    case TDMT_MND_CREATE_DB:
4,869✔
847
      return processCreateDbRsp;
4,869✔
848
    case TDMT_MND_USE_DB:
9,393✔
849
      return processUseDbRsp;
9,393✔
850
    case TDMT_MND_CREATE_STB:
7,216✔
851
      return processCreateSTableRsp;
7,216✔
852
    case TDMT_MND_DROP_DB:
3,535✔
853
      return processDropDbRsp;
3,535✔
854
    case TDMT_MND_ALTER_STB:
3,922✔
855
      return processAlterStbRsp;
3,922✔
856
    case TDMT_MND_SHOW_VARIABLES:
11✔
857
      return processShowVariablesRsp;
11✔
858
    case TDMT_MND_COMPACT_DB:
11✔
859
      return processCompactDbRsp;
11✔
860
    default:
9,220✔
861
      return genericRspCallback;
9,220✔
862
  }
863
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc