LCOV - code coverage report
Current view: top level - server - bqs_server.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.3 % 339 296
Test Date: 2026-08-12 11:05:07 Functions: 88.9 % 27 24

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "server/bqs_server.h"
      12              : 
      13              : #include <csignal>
      14              : #include <algorithm>
      15              : #include <securec.h>
      16              : #include "easy_comm.h"
      17              : #include "driver/ascend_hal.h"
      18              : 
      19              : #include "queue_manager.h"
      20              : #include "statistic_manager.h"
      21              : #include "router_server.h"
      22              : #include "common/bqs_log.h"
      23              : #include "aicpu_sched/common/type_def.h"
      24              : namespace bqs {
      25              : namespace {
      26              : // prevents concurrent execution of multiple clients
      27              : std::mutex g_bqsMutex;
      28              : 
      29              : constexpr const char_t* BQS_SERVER_THREAD_NAME_PREFIX = "bqs_server";
      30              : 
      31              : /**
      32              :  * Message process function, need to send a response to avoid blocking
      33              :  * @return NA
      34              :  */
      35            7 : void RpcHandler(const int32_t fd, EzcomRequest* const req)
      36              : {
      37            7 :     if (req == nullptr) {
      38            1 :         BQS_LOG_RUN_INFO("Pipe of client has been closed, fd:%d.", fd);
      39            1 :         (void)EzcomClosePipe(fd);
      40            1 :         return;
      41              :     }
      42              : 
      43            6 :     const std::unique_lock<std::mutex> lk(g_bqsMutex);
      44            6 :     BQS_LOG_INFO("BqsServer receive a request, id = %u, msg_size = %u", req->id, req->size);
      45            6 :     BqsServer::GetInstance().HandleBqsReqMsg(req->id, reinterpret_cast<const char_t*>(req->data), req->size);
      46              :     // send response
      47            6 :     BqsServer::GetInstance().SendRspMsg(fd, req->id);
      48            6 :     BQS_LOG_INFO("BqsServer HandleBqsReqMsg a request success, id = %u, msg_size = %u", req->id, req->size);
      49            6 :     return;
      50            6 : }
      51              : 
      52            0 : void NodeHandlerWrapper(const int32_t fd, const char_t* const clientName, const int32_t nameLen)
      53              : {
      54              :     (void)fd;
      55            0 :     if ((clientName == nullptr) || (nameLen <= 0)) {
      56            0 :         BQS_LOG_ERROR("Client name is nullptr");
      57            0 :         return;
      58              :     }
      59            0 :     (void)pthread_setname_np(pthread_self(), BQS_SERVER_THREAD_NAME_PREFIX);
      60              : }
      61              : } // namespace
      62              : 
      63            1 : BqsServer::BqsServer() : msgId_(0U), processing_(false), done_(false) {}
      64              : 
      65            1 : BqsServer::~BqsServer() {}
      66              : 
      67          134 : BqsServer& BqsServer::GetInstance()
      68              : {
      69          134 :     static BqsServer instance;
      70          134 :     return instance;
      71              : }
      72              : 
      73            5 : void BqsServer::InitBuff() const
      74              : {
      75            5 :     BuffCfg defaultCfg = {};
      76            5 :     const int32_t drvRet = halBuffInit(&defaultCfg);
      77            5 :     if ((drvRet != DRV_ERROR_NONE) && (drvRet != DRV_ERROR_REPEATED_INIT)) {
      78            0 :         BQS_LOG_ERROR("[BqsServer]Buffer initial failed ret[%d]", drvRet);
      79            0 :         return;
      80              :     }
      81            5 :     BQS_LOG_INFO("[RouterServer] Buffer init success ret = %d", drvRet);
      82              : }
      83              : 
      84              : /**
      85              :  * Bqs server handle BqsMsg, get/getall deal now, bind/unbind send to work thread to deal
      86              :  * @return NA
      87              :  */
      88            5 : void BqsServer::HandleBqsReqMsg(const uint32_t msgId, const char_t* const data, const uint32_t dataSize)
      89              : {
      90            5 :     BQS_LOG_INFO("Bind relation, stage [server:receive], type [request], msg [id = %u]", msgId);
      91            5 :     msgId_ = msgId;
      92            5 :     bqsRespMsg_.Clear(); // init response msg
      93            5 :     if (data == nullptr) {
      94            0 :         BQS_LOG_ERROR("Request of BqsClient is nullptr.");
      95            0 :         return;
      96              :     }
      97            5 :     if (dataSize < BQS_MSG_HEAD_SIZE) {
      98            0 :         BQS_LOG_ERROR("Request of BqsClient size:%u should be not less than head:%u.", dataSize, BQS_MSG_HEAD_SIZE);
      99            0 :         return;
     100              :     }
     101            5 :     InitBuff();
     102            5 :     const uint32_t currMsgSize = *(PtrToPtr<const char_t, const uint32_t>(data));
     103            5 :     if (currMsgSize != dataSize) {
     104            1 :         BQS_LOG_ERROR("message error, head_msg_content = %u, request_size = %u", currMsgSize, dataSize);
     105            1 :         return;
     106              :     }
     107            4 :     const uint32_t parseLength = currMsgSize - BQS_MSG_HEAD_SIZE;
     108            4 :     if (bqsReqMsg_.ParseFromArray(data + BQS_MSG_HEAD_SIZE, static_cast<int32_t>(parseLength))) {
     109            4 :         BQS_LOG_INFO(
     110              :             "BqsServer request msg type{%d:BIND, %d:UNBIND, %d:GET_BIND, %d:GET_ALL_BIND}:%d "
     111              :             "begin to process",
     112              :             BQSMsg::BIND, BQSMsg::UNBIND, BQSMsg::GET_BIND, BQSMsg::GET_ALL_BIND, bqsReqMsg_.msg_type());
     113            4 :         switch (bqsReqMsg_.msg_type()) {
     114            1 :             case BQSMsg::GET_BIND:
     115            1 :                 StatisticManager::GetInstance().GetBindStat();
     116            1 :                 ParseGetBindMsg(bqsReqMsg_, bqsRespMsg_);
     117            1 :                 break;
     118            1 :             case BQSMsg::GET_ALL_BIND:
     119            1 :                 StatisticManager::GetInstance().GetAllBindStat();
     120            1 :                 ParseGetPagedBindMsg(bqsReqMsg_, bqsRespMsg_);
     121            1 :                 break;
     122            1 :             case BQSMsg::BIND:
     123            1 :                 StatisticManager::GetInstance().BindStat();
     124            1 :                 WaitBindMsgProc();
     125            1 :                 break;
     126            0 :             case BQSMsg::UNBIND:
     127            0 :                 StatisticManager::GetInstance().UnbindStat();
     128            0 :                 WaitBindMsgProc();
     129            0 :                 break;
     130            1 :             default:
     131            1 :                 BQS_LOG_ERROR("BqsServer receive unsupported msg type:%d", bqsReqMsg_.msg_type());
     132            1 :                 break;
     133              :         }
     134              :     }
     135            4 :     BQS_LOG_INFO("BqsServer HandleBqsMsg end");
     136            4 :     return;
     137              : }
     138              : 
     139              : /**
     140              :  * Bqs server wait work thread to process msg
     141              :  * @return NA
     142              :  */
     143            0 : void BqsServer::WaitBindMsgProc()
     144              : {
     145            0 :     BQS_LOG_INFO("Bind relation [add/del], stage [server:enqueue], type [request], msg [id = %u]", msgId_);
     146            0 :     std::unique_lock<std::mutex> bqsLock(mutex_);
     147            0 :     const BqsStatus ret = QueueManager::GetInstance().EnqueueRelationEvent();
     148            0 :     if (ret == BQS_STATUS_OK) {
     149            0 :         done_ = false;
     150            0 :         BQS_LOG_INFO("Bind relation [add/del], stage [server:wait], type [request], msg [id = %u]", msgId_);
     151            0 :         (void)cv_.wait_for(bqsLock, std::chrono::milliseconds(MAX_WAITING_NOTIFY), [this] { return done_; });
     152            0 :         while ((!done_) && (processing_)) {
     153            0 :             cv_.wait(bqsLock);
     154              :         }
     155            0 :         if (!done_) {
     156            0 :             QueueManager::GetInstance().LogErrorRelationQueueStatus();
     157            0 :             BQS_LOG_ERROR(
     158              :                 "Bind relation [add/del], stage [server:wait], msg [id:%u] timeout, relation queue[enqueue "
     159              :                 "cnt:%lu, dequeue cnt:%lu].",
     160              :                 msgId_, StatisticManager::GetInstance().GetRelationEnqueCnt(),
     161              :                 StatisticManager::GetInstance().GetRelationDequeCnt());
     162              :         }
     163              :     }
     164            0 :     BQS_LOG_INFO("BqsServer WaitBindMsgProc end, msg [id = %u]", msgId_);
     165            0 :     return;
     166            0 : }
     167              : 
     168              : /**
     169              :  * Bqs server enqueue bind msg request process
     170              :  * @return NA
     171              :  */
     172            2 : void BqsServer::BindMsgProc()
     173              : {
     174            2 :     BQS_LOG_INFO("BqsServer BindMsgProc begin.");
     175              :     {
     176            2 :         const std::unique_lock<std::mutex> bqsLock(mutex_);
     177            2 :         processing_ = true;
     178            2 :     }
     179              :     // parse bind and unbind BQSMsg
     180            2 :     if (bqsReqMsg_.msg_type() == BQSMsg::BIND) {
     181            0 :         ParseBindMsg(bqsReqMsg_, bqsRespMsg_);
     182            2 :     } else if (bqsReqMsg_.msg_type() == BQSMsg::UNBIND) {
     183            0 :         ParseUnbindMsg(bqsReqMsg_, bqsRespMsg_);
     184              :     } else {
     185            2 :         BQS_LOG_ERROR("Invalid request type[%d]", static_cast<int32_t>(bqsReqMsg_.msg_type()));
     186              :     }
     187            2 :     bqsReqMsg_.Clear();
     188              : 
     189              :     {
     190            2 :         const std::unique_lock<std::mutex> bqsLock(mutex_);
     191            2 :         processing_ = false;
     192            2 :         done_ = true;
     193            2 :         cv_.notify_one();
     194            2 :     }
     195            2 :     BQS_LOG_INFO("BqsServer BindMsgProc end.");
     196            2 :     return;
     197              : }
     198              : 
     199              : /**
     200              :  * Init easycomm server, including register handler and start listening
     201              :  * @return BQS_STATUS_OK:success other:failed
     202              :  */
     203           98 : BqsStatus BqsServer::InitHandler() const
     204              : {
     205           98 :     BQS_LOG_INFO("BqsServer service handler init begin.");
     206              :     // easycomm start listening
     207           98 :     struct EzcomServerAttr serverAttr;
     208           98 :     serverAttr.openCallback = &NodeHandlerWrapper;
     209           98 :     serverAttr.handler = &RpcHandler;
     210           98 :     serverAttr.gid = qsGroupId_;
     211           98 :     const auto err = EzcomCreateServer(&serverAttr);
     212           98 :     if (err < 0) {
     213            0 :         BQS_LOG_ERROR(
     214              :             "Init server failed, another process may have already owned the server. "
     215              :             "errno = %d.",
     216              :             err);
     217            0 :         return BQS_STATUS_EASY_COMM_ERROR;
     218              :     }
     219           98 :     return BQS_STATUS_OK;
     220              : }
     221              : 
     222              : /**
     223              :  * Init bqs server, including init easycomm server and bind relation
     224              :  * @return BQS_STATUS_OK:success other:failed
     225              :  */
     226           98 : BqsStatus BqsServer::InitBqsServer(const std::string& qsInitGrpName, const uint32_t deviceId)
     227              : {
     228           98 :     BQS_LOG_INFO("BqsServer Init begin.");
     229              : 
     230           98 :     (void)signal(SIGPIPE, SIG_IGN);
     231              : 
     232           98 :     const BqsStatus ret = InitHandler();
     233           98 :     if (ret != BQS_STATUS_OK) {
     234            0 :         return ret;
     235              :     }
     236           98 :     qsInitGroupName_ = qsInitGrpName;
     237           98 :     deviceId_ = deviceId;
     238           98 :     BQS_LOG_INFO("BqsServer Init success.");
     239           98 :     return BQS_STATUS_OK;
     240              : }
     241              : 
     242              : /**
     243              :  * Bqs server send response msg to client, need to send a response to avoid blocking
     244              :  * @return NA
     245              :  */
     246           10 : void BqsServer::SendRspMsg(const int32_t fd, const uint32_t msgId) const
     247              : {
     248           10 :     BQS_LOG_INFO("Bind relation, stage [server:send], type [response], msg [fd = %d, id = %u]", fd, msgId);
     249              : 
     250           10 :     const uint32_t msgLen = static_cast<uint32_t>(bqsRespMsg_.ByteSizeLong());
     251           10 :     const uint32_t respLength = msgLen + BQS_MSG_HEAD_SIZE;
     252           10 :     char_t* const respData = new (std::nothrow) char_t[respLength];
     253           10 :     if (respData == nullptr) {
     254            0 :         BQS_LOG_ERROR("Malloc memory error, respData is nullptr");
     255            0 :         return;
     256              :     }
     257              : 
     258              :     // add msg length to check
     259           10 :     bool isOverflow = false;
     260           10 :     BqsCheckAssign32UAdd(msgLen, BQS_MSG_HEAD_SIZE, *(reinterpret_cast<uint32_t*>(respData)), isOverflow);
     261           10 :     if (isOverflow) {
     262            1 :         BQS_LOG_ERROR("msgLen[%u] is too big.", msgLen);
     263            1 :         delete[] respData;
     264            1 :         return;
     265              :     }
     266            9 :     if (!bqsRespMsg_.SerializePartialToArray(respData + BQS_MSG_HEAD_SIZE, static_cast<int32_t>(msgLen))) {
     267            1 :         BQS_LOG_ERROR("Serialize response msg failed.");
     268            1 :         delete[] respData;
     269            1 :         return;
     270              :     }
     271              : 
     272            8 :     EzcomResponse resp = {0U};
     273            8 :     resp.id = msgId;
     274            8 :     resp.data = reinterpret_cast<uint8_t*>(respData);
     275            8 :     resp.size = respLength;
     276            8 :     BQS_LOG_INFO("EzcomSendResponse begin, fd=%d, msgId=%u", fd, msgId);
     277            8 :     int32_t ret = EzcomSendResponse(fd, &resp);
     278            8 :     if (ret == -EAGAIN) {
     279              :         // just retry one times
     280            0 :         ret = EzcomSendResponse(fd, &resp);
     281            0 :         BQS_LOG_INFO("Need to retry ezcom send, fd=%d, msgId=%u", fd, msgId);
     282              :     }
     283            8 :     if (ret != 0) {
     284            1 :         BQS_LOG_ERROR("EzcomSendResponse end, fd=%d, msgId=%u, result=failed, ret=%d", fd, msgId, ret);
     285              :     } else {
     286            7 :         BQS_LOG_INFO("EzcomSendResponse end, fd=%d, msgId=%u, result=success", fd, msgId);
     287              :     }
     288              : 
     289            8 :     delete[] respData;
     290            8 :     StatisticManager::GetInstance().ResponseStat();
     291            8 :     return;
     292              : }
     293              : 
     294              : /**
     295              :  * Bqs server bind message processing function
     296              :  * @return NA
     297              :  */
     298            2 : void BqsServer::ParseBindMsg(BQSMsg& requestMsg, BQSMsg& responseMsg) const
     299              : {
     300            2 :     BQS_LOG_INFO("Bind relation [add], stage [server:process], type [request], msg [id:%u].", msgId_);
     301            2 :     BQSBindQueueMsgs* const bindQueueMsgs = requestMsg.mutable_bind_queue_msgs();
     302              : 
     303            2 :     BQSBindQueueRsps* const bqsBindQueueRspBuff = responseMsg.mutable_resp_msgs();
     304            2 :     auto& relationInstance = BindRelation::GetInstance();
     305              : 
     306            2 :     const uint32_t vecSize = static_cast<uint32_t>(bindQueueMsgs->bind_queue_vec_size());
     307           15 :     for (uint32_t i = 0U; i < vecSize; i++) {
     308           13 :         const BQSBindQueueMsg bindQueueMsg = bindQueueMsgs->bind_queue_vec(static_cast<int32_t>(i));
     309           13 :         const uint32_t srcQid = bindQueueMsg.src_queue_id();
     310           13 :         const uint32_t dstQid = bindQueueMsg.dst_queue_id();
     311              : 
     312              :         // add bind relation
     313           13 :         EntityInfo src(srcQid, deviceId_);
     314           13 :         EntityInfo dst(dstQid, deviceId_);
     315           13 :         int32_t result = BQS_STATUS_OK;
     316              :         // halQueueAttach third para 0 means attach without block
     317           13 :         auto drvRet = halQueueAttach(deviceId_, srcQid, 0);
     318           13 :         drvRet = (drvRet == DRV_ERROR_NONE) ? halQueueAttach(deviceId_, dstQid, 0) : drvRet;
     319           13 :         if (drvRet == DRV_ERROR_NONE) {
     320           13 :             result = relationInstance.Bind(src, dst);
     321              :         } else {
     322            0 :             BQS_LOG_ERROR("Fail to attach src queue[%u] or dst queue[%u], result[%d]", srcQid, dstQid, drvRet);
     323            0 :             result = BQS_STATUS_DRIVER_ERROR;
     324              :         }
     325           13 :         BQSBindQueueRsp* const bqsBindQueueInfo = bqsBindQueueRspBuff->add_bind_result_vec();
     326           13 :         bqsBindQueueInfo->set_bind_result(result);
     327           13 :         BQS_LOG_RUN_INFO(
     328              :             "Bind relation [add], stage [server:process], relation [srcQid:%u, dstQid:%u, result:%d]", srcQid, dstQid,
     329              :             result);
     330           13 :     }
     331            2 :     relationInstance.Order();
     332            2 :     return;
     333              : }
     334              : 
     335              : /**
     336              :  * Bqs server unbind message processing function
     337              :  * @return unbind result, BQS_STATUS_OK:success other:failed
     338              :  */
     339              : 
     340           40 : int32_t BqsServer::UnbindRelation(
     341              :     BindRelation& relationInstance, const BQSQueryMsg::QsQueryType& queryType, EntityInfo& srcId,
     342              :     EntityInfo& dstId) const
     343              : {
     344           40 :     int32_t result = BQS_STATUS_INNER_ERROR;
     345           40 :     switch (queryType) {
     346           10 :         case BQSQueryMsg::BQS_QUERY_TYPE_SRC:
     347           10 :             result = relationInstance.UnBindBySrc(srcId);
     348           10 :             BQS_LOG_RUN_INFO(
     349              :                 "Bind relation [del], stage [server:process], relation [query type:src, src = %u, "
     350              :                 "result = %d]",
     351              :                 srcId.GetId(), result);
     352           10 :             break;
     353           10 :         case BQSQueryMsg::BQS_QUERY_TYPE_DST:
     354           10 :             result = relationInstance.UnBindByDst(dstId);
     355           10 :             BQS_LOG_RUN_INFO(
     356              :                 "Bind relation [del], stage [server:process], relation [query type:dst, dst:%u, result:%d]",
     357              :                 dstId.GetId(), result);
     358           10 :             break;
     359           10 :         case BQSQueryMsg::BQS_QUERY_TYPE_SRC_AND_DST:
     360           10 :             result = relationInstance.UnBind(srcId, dstId);
     361           10 :             BQS_LOG_RUN_INFO(
     362              :                 "Bind relation [del], stage [server:process], relation [query type:src-dst, src:%u, dst:%u, result:%d]",
     363              :                 srcId.GetId(), dstId.GetId(), result);
     364           10 :             break;
     365           10 :         default:
     366           10 :             BQS_LOG_ERROR("BqsServer unbind error, unsupported query type{0:src, 1:dst, 2:src-dst}:%d", queryType);
     367           10 :             break;
     368              :     }
     369           40 :     return result;
     370              : }
     371              : 
     372              : /**
     373              :  * Bqs server unbind message processing function
     374              :  * @return NA
     375              :  */
     376            4 : void BqsServer::ParseUnbindMsg(BQSMsg& requestMsg, BQSMsg& responseMsg) const
     377              : {
     378            4 :     BQS_LOG_INFO("Bind relation [del], stage [server:process], type [request], msg [id = %u].", msgId_);
     379            4 :     BQSQueryMsgs* const bqsQueryMsgBuff = requestMsg.mutable_query_msgs();
     380              : 
     381            4 :     BQSBindQueueRsps* const bqsBindQueueRspBuff = responseMsg.mutable_resp_msgs();
     382              : 
     383            4 :     auto& relationInstance = BindRelation::GetInstance();
     384              : 
     385           44 :     for (int32_t i = 0; i < bqsQueryMsgBuff->query_msg_vec_size(); i++) {
     386           40 :         BQSQueryMsg bqsQueryInfo = bqsQueryMsgBuff->query_msg_vec(i);
     387           40 :         const BQSQueryMsg::QsQueryType keyType = bqsQueryInfo.key_type();
     388           40 :         BQSBindQueueMsg* const bindQueueinfo = bqsQueryInfo.mutable_bind_queue_item();
     389              : 
     390           40 :         const uint32_t srcQid = bindQueueinfo->src_queue_id();
     391           40 :         const uint32_t dstQid = bindQueueinfo->dst_queue_id();
     392           40 :         EntityInfo src(srcQid, deviceId_);
     393           40 :         EntityInfo dst(dstQid, deviceId_);
     394              : 
     395              :         // delete bind relation
     396           40 :         const int32_t result = UnbindRelation(relationInstance, keyType, src, dst);
     397              : 
     398           40 :         BQSBindQueueRsp* const relationProcessRsp = bqsBindQueueRspBuff->add_bind_result_vec();
     399           40 :         relationProcessRsp->set_bind_result(result);
     400           40 :     }
     401              : 
     402            4 :     relationInstance.Order();
     403            4 :     return;
     404              : }
     405              : 
     406              : /**
     407              :  * Assembly response of get bind message according to src queueId
     408              :  * @return NA
     409              :  */
     410            4 : void BqsServer::SerializeGetBindRspBySrc(const uint32_t srcId, BQSMsg& responseMsg) const
     411              : {
     412            4 :     BQS_LOG_INFO("BqsServer serialize get bind rsponse by src begin, srcId:%u", srcId);
     413            4 :     const EntityInfo src(srcId, deviceId_);
     414            4 :     auto& relationInstance = BindRelation::GetInstance();
     415              : 
     416              :     // Find all dst queue id who has subscribed to the src queue id
     417            4 :     auto& srcToDstRelation = relationInstance.GetSrcToDstRelation();
     418            4 :     const auto iter = srcToDstRelation.find(src);
     419              : 
     420            4 :     const auto& abnormalSrcToDstRelation = relationInstance.GetAbnormalSrcToDstRelation();
     421            4 :     const auto abnormalIter = abnormalSrcToDstRelation.find(src);
     422            4 :     if (iter == srcToDstRelation.end() && abnormalIter == abnormalSrcToDstRelation.end()) {
     423            2 :         BQS_LOG_WARN("BqsServer get relation according to src:%u failed, record does not exist", src.GetId());
     424            2 :         return;
     425              :     }
     426              : 
     427            2 :     BQSBindQueueMsgs* const bqsBindQueueMsgBuff = responseMsg.mutable_bind_queue_msgs();
     428            2 :     if (iter != srcToDstRelation.end()) {
     429            2 :         FillGetBindRspBySrc(srcId, iter->second, false, bqsBindQueueMsgBuff);
     430              :     }
     431            2 :     if (abnormalIter != abnormalSrcToDstRelation.end()) {
     432            1 :         FillGetBindRspBySrc(srcId, abnormalIter->second, true, bqsBindQueueMsgBuff);
     433              :     }
     434            4 : }
     435              : 
     436              : /**
     437              :  * Fill getBind response by src and dstSet, one-to-one relation
     438              :  * @return NA
     439              :  */
     440            3 : void BqsServer::FillGetBindRspBySrc(
     441              :     const uint32_t srcId, const std::unordered_set<EntityInfo, EntityInfoHash>& dstSet, bool isAbnormal,
     442              :     BQSBindQueueMsgs* const bqsBindQueueMsgBuff) const
     443              : {
     444            3 :     BQS_LOG_INFO("Bind relation [get], stage [server:process], relation [size:%zu].", dstSet.size());
     445            3 :     int32_t i = 0;
     446            6 :     for (auto setIter = dstSet.begin(); setIter != dstSet.end(); ++setIter) {
     447            3 :         BQSBindQueueMsg* const bqsBindQueueInfo = bqsBindQueueMsgBuff->add_bind_queue_vec();
     448            3 :         bqsBindQueueInfo->set_src_queue_id(srcId);
     449            3 :         const EntityInfo dstQ = *setIter;
     450            3 :         bqsBindQueueInfo->set_dst_queue_id(dstQ.GetId());
     451            3 :         ++i;
     452            3 :         BQS_LOG_INFO(
     453              :             "Bind relation [get], stage [server:process], relation [abnormal:%d, index:%d, src:%u, dst:%u]",
     454              :             static_cast<int32_t>(isAbnormal), i, srcId, dstQ.GetId());
     455            3 :     }
     456            3 : }
     457              : 
     458              : /**
     459              :  * Assembly response of get bind message according to dst queueId, one-to-one relation
     460              :  * @return NA
     461              :  */
     462            3 : void BqsServer::SerializeGetBindRspByDst(const uint32_t dstId, BQSMsg& responseMsg) const
     463              : {
     464            3 :     BQS_LOG_INFO("BqsServer serialize get bind rsponse by dst begin, dstId:%u", dstId);
     465            3 :     auto& relationInstance = BindRelation::GetInstance();
     466            3 :     const EntityInfo dst(dstId, deviceId_);
     467              : 
     468            3 :     auto& dstToSrcRelation = relationInstance.GetDstToSrcRelation();
     469            3 :     const auto iter = dstToSrcRelation.find(dst);
     470              : 
     471            3 :     const auto& abnormalDstToSrcRelation = relationInstance.GetAbnormalDstToSrcRelation();
     472            3 :     const auto abnormalIter = abnormalDstToSrcRelation.find(dst);
     473            3 :     if ((iter == dstToSrcRelation.end()) && (abnormalIter == abnormalDstToSrcRelation.end())) {
     474            1 :         BQS_LOG_WARN("BqsServer get relation according to dst:%u failed, record does not exist", dstId);
     475            1 :         return;
     476              :     }
     477              : 
     478            2 :     BQSBindQueueMsgs* const bqsBindQueueMsgBuff = responseMsg.mutable_bind_queue_msgs();
     479            2 :     if (iter != dstToSrcRelation.end()) {
     480            2 :         FillGetBindRspByDst(iter->second, dstId, false, bqsBindQueueMsgBuff);
     481              :     }
     482            2 :     if (abnormalIter != abnormalDstToSrcRelation.end()) {
     483            1 :         FillGetBindRspByDst(abnormalIter->second, dstId, true, bqsBindQueueMsgBuff);
     484              :     }
     485            3 : }
     486              : 
     487              : /**
     488              :  * Fill getBind response by srcSet and dst, one-to-one relation
     489              :  * @return NA
     490              :  */
     491            3 : void BqsServer::FillGetBindRspByDst(
     492              :     const std::unordered_set<EntityInfo, EntityInfoHash>& srcSet, const uint32_t dstId, bool isAbnormal,
     493              :     BQSBindQueueMsgs* const bqsBindQueueMsgBuff) const
     494              : {
     495            3 :     BQS_LOG_INFO("Bind relation [get], stage [server:process], relation [size:%zu].", srcSet.size());
     496            3 :     int32_t i = 0;
     497            6 :     for (auto setIter = srcSet.begin(); setIter != srcSet.end(); ++setIter) {
     498            3 :         BQSBindQueueMsg* const bqsBindQueueInfo = bqsBindQueueMsgBuff->add_bind_queue_vec();
     499            3 :         bqsBindQueueInfo->set_src_queue_id(setIter->GetId());
     500            3 :         bqsBindQueueInfo->set_dst_queue_id(dstId);
     501            3 :         ++i;
     502            3 :         BQS_LOG_INFO(
     503              :             "Bind relation [get], stage [server:process], relation [abnormal:%d, index:%d, src:%u, dst:%u]",
     504              :             static_cast<int32_t>(isAbnormal), i, setIter->GetId(), dstId);
     505              :     }
     506            3 : }
     507              : 
     508              : /**
     509              :  * Assembly response of get bind message
     510              :  * @return NA
     511              :  */
     512            6 : void BqsServer::SerializeGetBindRsp(
     513              :     const BQSQueryMsg::QsQueryType& queryType, const uint32_t srcId, const uint32_t dstId, BQSMsg& responseMsg) const
     514              : {
     515            6 :     switch (queryType) {
     516            3 :         case BQSQueryMsg::BQS_QUERY_TYPE_SRC:
     517            3 :             SerializeGetBindRspBySrc(srcId, responseMsg);
     518            3 :             break;
     519            2 :         case BQSQueryMsg::BQS_QUERY_TYPE_DST:
     520            2 :             SerializeGetBindRspByDst(dstId, responseMsg);
     521            2 :             break;
     522            1 :         default:
     523            1 :             BQS_LOG_ERROR("BqsServer get bind error, unsupported query type{0:src, 1:dst, 2:src-dst}:%d", queryType);
     524            1 :             break;
     525              :     }
     526            6 :     return;
     527              : }
     528              : 
     529              : /**
     530              :  * Bqs server get bind message processing function
     531              :  * @return NA
     532              :  */
     533            6 : void BqsServer::ParseGetBindMsg(BQSMsg& requestMsg, BQSMsg& responseMsg) const
     534              : {
     535            6 :     BQS_LOG_INFO("Bind relation [get], stage [server:process], type [request], msg [id:%u].", msgId_);
     536            6 :     BQSQueryMsg* const bqsQueryInfo = requestMsg.mutable_query_msg();
     537              : 
     538            6 :     const BQSQueryMsg::QsQueryType keyType = bqsQueryInfo->key_type();
     539            6 :     BQSBindQueueMsg* const bqsBindQueueInfo = bqsQueryInfo->mutable_bind_queue_item();
     540              : 
     541            6 :     const uint32_t src = bqsBindQueueInfo->src_queue_id();
     542            6 :     const uint32_t dst = bqsBindQueueInfo->dst_queue_id();
     543              : 
     544            6 :     SerializeGetBindRsp(keyType, src, dst, responseMsg);
     545           12 :     return;
     546              : }
     547              : 
     548              : /**
     549              :  * Bqs server get paged bind message processing function
     550              :  * @return NA
     551              :  */
     552            2 : void BqsServer::ParseGetPagedBindMsg(BQSMsg& requestMsg, BQSMsg& responseMsg) const
     553              : {
     554            2 :     BQS_LOG_INFO("Bind relation [get_all], stage [server:process], type [request], msg [id:%u].", msgId_);
     555            2 :     BQSBindQueueMsgs* const bqsBindQueueMsgBuff = responseMsg.mutable_bind_queue_msgs();
     556              : 
     557            2 :     BQSPagedMsg* const pagedMsg = requestMsg.mutable_paged_msg();
     558              : 
     559            2 :     BQSPagedMsg* const pagedRspMsg = responseMsg.mutable_paged_msg();
     560              : 
     561            2 :     auto& relationInstance = BindRelation::GetInstance();
     562              : 
     563            2 :     static std::vector<std::tuple<uint32_t, uint32_t>> relations;
     564              :     static uint32_t offsetSave = 0U;
     565              :     static uint32_t total = 0U;
     566            2 :     const uint32_t msgOffset = pagedMsg->offset();
     567            2 :     if ((msgOffset == 0U) || (msgOffset < offsetSave) || relations.empty()) {
     568            2 :         auto& srcToDstRelation = relationInstance.GetSrcToDstRelation();
     569            2 :         RelationsCopy(relations, total, srcToDstRelation);
     570            2 :         AppendRelations(relations, relationInstance.GetAbnormalSrcToDstRelation());
     571            2 :         offsetSave = msgOffset;
     572            2 :         total = static_cast<uint32_t>(relations.size());
     573              :     }
     574            2 :     pagedRspMsg->set_total(total);
     575            2 :     const uint32_t offset = (msgOffset > total) ? total : msgOffset;
     576            2 :     const uint32_t limit = pagedMsg->limit();
     577              : 
     578              :     // get bind relation
     579            2 :     uint32_t i = 0U;
     580            2 :     auto iter = relations.begin();
     581            2 :     BQS_LOG_INFO(
     582              :         "Bind relation [get_paged], stage [server:process], relation [offset:%u, limit:%u, size:%u]",
     583              :         pagedMsg->offset(), limit, total);
     584              :     std::advance(iter, offset);
     585           12 :     while ((iter != relations.end()) && (i < limit)) {
     586           10 :         const uint32_t srcId = std::get<0>(*iter);
     587           10 :         const uint32_t dstId = std::get<1>(*iter);
     588           10 :         BQSBindQueueMsg* const bqsBindQueueInfo = bqsBindQueueMsgBuff->add_bind_queue_vec();
     589              : 
     590           10 :         bqsBindQueueInfo->set_src_queue_id(srcId);
     591           10 :         bqsBindQueueInfo->set_dst_queue_id(dstId);
     592           10 :         ++iter;
     593           10 :         ++i;
     594              :     }
     595            4 :     return;
     596              : }
     597              : 
     598              : /**
     599              :  * Copy relation map to a vector container
     600              :  * @return NA
     601              :  */
     602            2 : void BqsServer::RelationsCopy(
     603              :     std::vector<std::tuple<uint32_t, uint32_t>>& relations, const uint32_t oldSize,
     604              :     const std::unordered_map<EntityInfo, std::unordered_set<EntityInfo, EntityInfoHash>, EntityInfoHash>& srcMap) const
     605              : {
     606            2 :     relations.clear();
     607            2 :     if (oldSize != 0U) {
     608            0 :         relations.reserve(static_cast<std::vector<std::tuple<uint32_t, uint32_t>>::size_type>(oldSize));
     609              :     }
     610            3 :     for (const auto& iter : srcMap) {
     611            1 :         (void)std::transform(
     612              :             iter.second.begin(), iter.second.end(), std::back_inserter(relations),
     613           10 :             [&](const EntityInfo entityInfo) { return std::make_pair(iter.first.GetId(), entityInfo.GetId()); });
     614              :     }
     615            2 : }
     616              : 
     617              : /**
     618              :  * append relations to a vector container
     619              :  * @return NA
     620              :  */
     621            3 : void BqsServer::AppendRelations(
     622              :     std::vector<std::tuple<uint32_t, uint32_t>>& relations,
     623              :     const std::unordered_map<EntityInfo, std::unordered_set<EntityInfo, EntityInfoHash>, EntityInfoHash>& srcMap) const
     624              : {
     625            5 :     for (const auto& iter : srcMap) {
     626            2 :         (void)std::transform(
     627              :             iter.second.begin(), iter.second.end(), std::back_inserter(relations),
     628            3 :             [&](const EntityInfo entityInfo) { return std::make_pair(iter.first.GetId(), entityInfo.GetId()); });
     629              :     }
     630            3 : }
     631              : 
     632              : } // namespace bqs
        

Generated by: LCOV version 2.0-1