void NlsClientImpl::releaseRequest()

in nlsCppSdk/framework/common/nlsClientImpl.cpp [429:646]


void NlsClientImpl::releaseRequest(INlsRequest *request) {
  uint64_t timewait_start, timewait_end;
  timewait_start = utility::TextUtils::GetTimestampMs();

  if (request == NULL) {
    LOG_ERROR("Input request is nullptr, you have destroyed request!");
    return;
  }
  if (request->getConnectNode() == NULL) {
    LOG_ERROR("The node in request(%p) is nullptr, you have destroyed request!",
              request);
    return;
  }

  int status = NodeStatusInvalid;
  int ret = _nodeManager->checkRequestExist(request, &status);
  if (ret != Success) {
    LOG_ERROR("Request(%p) checkRequestExist0 failed, %d.", request, ret);
    return;
  }

  /* 准备移出request, 上锁保护, 防止其他线程也同时在释放 */
  bool release_lock_ret = true;
  NlsClientImpl *cur_instance = request->getConnectNode()->getInstance();
  if (cur_instance != NULL) {
#ifdef ENABLE_NLS_DEBUG_2
    LOG_DEBUG("Request(%p) Node(%p) trylock with %p.", request,
              request->getConnectNode(),
              &cur_instance->_mtxReleaseRequestGuard);
#endif
    MUTEX_TRY_LOCK_WITH_TAG(cur_instance->_mtxReleaseRequestGuard, 2000,
                            release_lock_ret, request);
    if (!release_lock_ret) {
      LOG_ERROR("Request(%p) lock destroy failed, deadlock has occurred",
                request);
    }
  } else {
    LOG_INFO("Request(%p) just only created ...", request);
    release_lock_ret = false;
  }

  ret = _nodeManager->checkRequestExist(request, &status);
  if (ret != Success) {
    LOG_ERROR("Request(%p) checkRequestExist1 failed, %d.", request, ret);
    if (release_lock_ret) {
      MUTEX_UNLOCK_WITH_TAG(cur_instance->_mtxReleaseRequestGuard, request);
    }
    return;
  }

  request->getConnectNode()->_releasingFlag = true;

  LOG_INFO("Begin release, request(%p) node(%p) node status:%s exit status:%s.",
           request, request->getConnectNode(),
           request->getConnectNode()->getConnectNodeStatusString().c_str(),
           request->getConnectNode()->getExitStatusString().c_str());

  evutil_socket_t curSocketFd = request->getConnectNode()->getSocketFd();
  SSLconnect *curSslHandle = request->getConnectNode()->getSslHandle();
  SSLconnect *curNativeSslHandle =
      request->getConnectNode()->getNativeSslHandle();
  NlsType type = request->getRequestParam()->_mode;
  INlsRequest *curRequest = request;
  bool sslInConnectedPool = false;
  bool oriRequestIsAbnormal = false;
  bool requestInPool = false;
#ifdef ENABLE_PRECONNECTED_POOL
  if (request->getConnectNode()->isUsingPreconnection() &&
      NlsEventNetWork::_eventClient &&
      NlsEventNetWork::_eventClient->getPreconnectedPool()) {
    if (NlsEventNetWork::_eventClient->getPreconnectedPool()->sslBelongToPool(
            request, type, oriRequestIsAbnormal, requestInPool)) {
      sslInConnectedPool = true;
      if (oriRequestIsAbnormal) {
        LOG_WARN(
            "Request(%p) node(%p) has stored in ConnectedPool, with %s "
            "usePreconnection and SSL(%p), native SSL(%p). But current request "
            "is abnormal.",
            request, request->getConnectNode(),
            request->getConnectNode()->isUsingPreconnection() ? "enable"
                                                              : "disable",
            request->getConnectNode()->getSslHandle(),
            request->getConnectNode()->getNativeSslHandle());
      } else {
        LOG_DEBUG(
            "Request(%p) node(%p) has stored in ConnectedPool, with %s "
            "usePreconnection and SSL(%p), native SSL(%p).",
            request, request->getConnectNode(),
            request->getConnectNode()->isUsingPreconnection() ? "enable"
                                                              : "disable",
            request->getConnectNode()->getSslHandle(),
            request->getConnectNode()->getNativeSslHandle());
      }
    } else {
      LOG_DEBUG(
          "Request(%p) node(%p) not stored in ConnectedPool, with %s "
          "usePreconnection and SSL(%p), native SSL(%p).",
          request, request->getConnectNode(),
          request->getConnectNode()->isUsingPreconnection() ? "enable"
                                                            : "disable",
          request->getConnectNode()->getSslHandle(),
          request->getConnectNode()->getNativeSslHandle());
    }
  }
#endif

  request->getConnectNode()->delAllEvents();

  if (!sslInConnectedPool) {
    request->getConnectNode()->updateDestroyStatus();
  }

  int index = request->getConnectNode()->getPoolIndex();

  ret = _nodeManager->removeRequestFromInfo(request, false);
  if (ret == Success) {
#ifdef ENABLE_PRECONNECTED_POOL
    // if (sslInConnectedPool) {
    //   if (oriRequestIsAbnormal) {
    //     LOG_INFO(
    //         "Request(%p) Node(%p) with SSL handle(%p) socketFd(%d) has stored
    //         " "in ConnectedPool, and orignal request is abnormal, should
    //         delete " "itself.", request, request->getConnectNode(),
    //         curSslHandle, curSocketFd);
    //     delete request;
    //   }
    // } else {
    //   LOG_DEBUG(
    //       "Request(%p) Node(%p) with SSL handle(%p) socketFd(%d) is not
    //       stored " "in ConnectedPool, should delete.", request,
    //       request->getConnectNode(), curSslHandle, curSocketFd);
    //   delete request;
    // }
    if (requestInPool) {
      LOG_INFO(
          "Request(%p) Node(%p) with SSL handle(%p) socketFd(%d) has stored "
          "in ConnectedPool, and it is orignal request, should delete "
          "itself later, not here.",
          request, request->getConnectNode(), curSslHandle, curSocketFd);
    } else {
      LOG_DEBUG(
          "Request(%p) Node(%p) with SSL handle(%p) socketFd(%d) did not "
          "stored "
          "in ConnectedPool, delete here.",
          request, request->getConnectNode(), curSslHandle, curSocketFd);
      delete request;
    }
#else
    delete request;
#endif
  } else {
    LOG_ERROR("Release request(%p) is invalid, skip ...", request);
  }
  request = NULL;

  if (sslInConnectedPool) {
    if (oriRequestIsAbnormal) {
      LOG_INFO(
          "Request(%p) SSL(%p) and socketFd(%d) index(%d) has stored in "
          "ConnectedPool, and orignal request is abnormal, should delete this "
          "orignal request in ConnectedPool.",
          curRequest, curSslHandle, curSocketFd, index);
#ifdef ENABLE_PRECONNECTED_POOL
      if (NlsEventNetWork::_eventClient &&
          NlsEventNetWork::_eventClient->getPreconnectedPool()) {
        NlsEventNetWork::_eventClient->getPreconnectedPool()
            ->deletePreNodeBySSL(curSslHandle, type);
      }
#endif
    } else {
      LOG_DEBUG(
          "Request(%p) SSL(%p) and socketFd(%d) index(%d) has stored in "
          "ConnectedPool, "
          "and will release later "
          "in "
          "ConnectedPool.",
          curRequest, curSslHandle, curSocketFd, index);
#ifdef ENABLE_PRECONNECTED_POOL
      if (NlsEventNetWork::_eventClient &&
          NlsEventNetWork::_eventClient->getPreconnectedPool()) {
        NlsEventNetWork::_eventClient->getPreconnectedPool()->finishPushPreNode(
            type, curSocketFd, curSslHandle, index, curRequest);
      }
#endif
    }
  } else {
    LOG_DEBUG(
        "Request(%p) SSL(%p) NativeSSL(%p) and socketFd(%d) index(%d) not "
        "stored in ConnectedPool, "
        "and remove this request from ConnectedPool.",
        curRequest, curSslHandle, curNativeSslHandle, curSocketFd, index);
#ifdef ENABLE_PRECONNECTED_POOL
    if (NlsEventNetWork::_eventClient &&
        NlsEventNetWork::_eventClient->getPreconnectedPool()) {
      NlsEventNetWork::_eventClient->getPreconnectedPool()
          ->deletePreNodeByRequest(curRequest, type);
    }
#endif
  }

  if (release_lock_ret) {
    MUTEX_UNLOCK_WITH_TAG(cur_instance->_mtxReleaseRequestGuard, curRequest);
  }
#ifdef ENABLE_NLS_DEBUG_2
  else {
    LOG_WARN("_mtxReleaseRequestGuard isnot unlock.");
  }
  LOG_DEBUG("Release request(%p) done.", curRequest);
#endif

  timewait_end = utility::TextUtils::GetTimestampMs();
  if (timewait_end - timewait_start > 50) {
    LOG_ERROR("Release request(%p) excessive latency:%llums", curRequest,
              timewait_end - timewait_start);
  }

  return;
}