HTTPSession::createTransaction(
    HTTPCodec::StreamID streamID,
    const folly::Optional<HTTPCodec::StreamID>& assocStreamID,
    const folly::Optional<HTTPCodec::ExAttributes>& exAttributes,
    const http2::PriorityUpdate& priority) {
  if (!sock_->good() || transactions_.count(streamID)) {
    // Refuse to add a transaction on a closing session or if a
    // transaction of that ID already exists.
    return nullptr;
  }

  if (transactions_.empty()) {
    if (infoCallback_) {
      infoCallback_->onActivateConnection(*this);
    }
    if (getConnectionManager()) {
      getConnectionManager()->onActivated(*this);
    }
    HTTPSessionBase::onCreateTransaction();
  }

  auto matchPair = transactions_.emplace(
    std::piecewise_construct,
    std::forward_as_tuple(streamID),
    std::forward_as_tuple(
      codec_->getTransportDirection(), streamID, getNumTxnServed(), *this,
      txnEgressQueue_, timeout_.getWheelTimer(), timeout_.getDefaultTimeout(),
      sessionStats_,
      codec_->supportsStreamFlowControl(),
      initialReceiveWindow_,
      getCodecSendWindowSize(),
      priority,
      assocStreamID,
      exAttributes
    ));

  CHECK(matchPair.second) << "Emplacement failed, despite earlier "
    "existence check.";

  HTTPTransaction* txn = &matchPair.first->second;

  if (isPrioritySampled()) {
    txn->setPrioritySampled(true /* sampled */);
  }

  if (getNumTxnServed() > 0) {
    auto stats = txn->getSessionStats();
    if (stats != nullptr) {
      stats->recordSessionReused();
    }
  }

  VLOG(5) << *this << " adding streamID=" << txn->getID()
          << ", liveTransactions_ was " << liveTransactions_;

  ++liveTransactions_;
  incrementSeqNo();
  txn->setReceiveWindow(receiveStreamWindowSize_);

  if (isUpstream() && !txn->isPushed()) {
    incrementOutgoingStreams();
  // do not count towards MAX_CONCURRENT_STREAMS for PUSH_PROMISE
  } else if (!(isDownstream() && txn->isPushed())) {
    incomingStreams_++;
  }

  return txn;
}
HTTPSession::createTransaction(
    HTTPCodec::StreamID streamID,
    const folly::Optional<HTTPCodec::StreamID>& assocStreamID,
    const folly::Optional<HTTPCodec::ExAttributes>& exAttributes,
    const http2::PriorityUpdate& priority) {
  if (!sock_->good() || transactions_.count(streamID)) {
     
     
    return nullptr;
  }

  if (transactions_.empty()) {
    if (infoCallback_) {
      infoCallback_->onActivateConnection(*this);
    }
    if (getConnectionManager()) {
      getConnectionManager()->onActivated(*this);
    }
    HTTPSessionBase::onCreateTransaction();
  }

  auto matchPair = transactions_.emplace(
    std::piecewise_construct,
    std::forward_as_tuple(streamID),
    std::forward_as_tuple(
      codec_->getTransportDirection(), streamID, getNumTxnServed(), *this,
      txnEgressQueue_, timeout_.getWheelTimer(), timeout_.getDefaultTimeout(),
      sessionStats_,
      codec_->supportsStreamFlowControl(),
      initialReceiveWindow_,
      getCodecSendWindowSize(),
      priority,
      assocStreamID,
      exAttributes
    ));

  CHECK(matchPair.second) << "Emplacement failed, despite earlier "
    "existence check.";

  HTTPTransaction* txn = &matchPair.first->second;

  if (isPrioritySampled()) {
    txn->setPrioritySampled(true  );
  }

  if (getNumTxnServed() > 0) {
    auto stats = txn->getSessionStats();
    if (stats != nullptr) {
      stats->recordSessionReused();
    }
  }

  VLOG(5) << *this << " adding streamID=" << txn->getID()
          << ", liveTransactions_ was " << liveTransactions_;

  ++liveTransactions_;
  incrementSeqNo();
  txn->setReceiveWindow(receiveStreamWindowSize_);

  if (isUpstream() && !txn->isPushed()) {
    incrementOutgoingStreams();
   
  } else if (!(isDownstream() && txn->isPushed())) {
    incomingStreams_++;
  }

  return txn;
}