@@ -505,15 +505,21 @@ void TCPTransport::ReadLoop() {
505505 std::vector<uint8_t > body (body_size);
506506 std::memcpy (body.data (), payload.data () + PROTOCOL_HEADER_SIZE , body_size);
507507
508- // Route to pending request
509- std::lock_guard<std::mutex> lock (pending_mutex_);
510- auto it = pending_responses_. find (req_id);
511- if (it != pending_responses_. end ()) {
512- it-> second -> Signal ( std::move (body), msg_id );
508+ if ( protocol::IsRequest (msg_id)) {
509+ // Agent -> Provider call: dispatch to bounded worker pool.
510+ // (Read loop never executes handler logic — inline processing
511+ // would head-of-line block every request on one slow handler.)
512+ DispatchInbound (msg_id, req_id, std::move (body));
513513 } else {
514- // Debug: log unmatched response
515- std::cerr << " [DEBUG] TCPTransport: Received response for unknown req_id: " << req_id
516- << " , msg_id: " << msg_id << " , body_size: " << body_size << ' \n ' ;
514+ // Route response to pending request
515+ std::lock_guard<std::mutex> lock (pending_mutex_);
516+ auto it = pending_responses_.find (req_id);
517+ if (it != pending_responses_.end ()) {
518+ it->second ->Signal (std::move (body), msg_id);
519+ } else {
520+ std::cerr << " [DEBUG] TCPTransport: Received response for unknown req_id: " << req_id
521+ << " , msg_id: " << msg_id << " , body_size: " << body_size << ' \n ' ;
522+ }
517523 }
518524 }
519525
@@ -908,5 +914,83 @@ bool TCPServer::SendMessage(socket_t sock, uint32_t msg_type, uint32_t req_id, c
908914 return sent == static_cast <ssize_t >(frame.size ());
909915}
910916
917+ // ---- Inbound dispatch ----
918+
919+ int TCPTransport::InboundWorkerCount () {
920+ unsigned int n = std::thread::hardware_concurrency ();
921+ return n == 0 ? 2 : static_cast <int >(std::max (2u , n));
922+ }
923+
924+ void TCPTransport::SetInboundHandler (InboundHandler handler) {
925+ inbound_handler_ = std::move (handler);
926+ }
927+
928+ void TCPTransport::DispatchInbound (uint32_t msg_id, uint32_t req_id, std::vector<uint8_t > body) {
929+ if (!inbound_handler_) {
930+ return ;
931+ }
932+ // 惰性启动固定 worker 池(默认 = 硬件并发数)
933+ {
934+ std::lock_guard<std::mutex> lock (inbound_pool_mutex_);
935+ if (!inbound_pool_started_) {
936+ int workers = InboundWorkerCount ();
937+ for (int i = 0 ; i < workers; ++i) {
938+ inbound_workers_.emplace_back ([this ] {
939+ for (;;) {
940+ std::tuple<uint32_t , uint32_t , std::vector<uint8_t >> task;
941+ {
942+ std::unique_lock<std::mutex> lock (inbound_pool_mutex_);
943+ inbound_cv_.wait (lock, [this ] { return !inbound_queue_.empty (); });
944+ task = std::move (inbound_queue_.front ());
945+ inbound_queue_.pop ();
946+ }
947+ auto [mid, rid, tbody] = std::move (task);
948+ std::vector<uint8_t > resp;
949+ try {
950+ resp = inbound_handler_ (mid, rid, tbody);
951+ } catch (const std::exception& e) {
952+ std::cerr << " [ERROR] inbound handler: " << e.what () << ' \n ' ;
953+ resp.clear ();
954+ }
955+ WriteResponseSilently (protocol::GetResponseMsgID (mid), rid, resp);
956+ inbound_queued_.fetch_sub (1 );
957+ }
958+ });
959+ }
960+ inbound_pool_started_ = true ;
961+ }
962+ }
963+ int workers = InboundWorkerCount ();
964+ if (inbound_queued_.load () >= workers * 4 ) {
965+ // 队列满:立即回空响应,Agent 侧 failover 接管。
966+ std::cerr << " [WARN] inbound queue full, fast-failing req_id=" << req_id << ' \n ' ;
967+ WriteResponseSilently (protocol::GetResponseMsgID (msg_id), req_id, {});
968+ return ;
969+ }
970+ inbound_queued_.fetch_add (1 );
971+ {
972+ std::lock_guard<std::mutex> lock (inbound_pool_mutex_);
973+ inbound_queue_.emplace (msg_id, req_id, std::move (body));
974+ }
975+ inbound_cv_.notify_one ();
976+ }
977+
978+ void TCPTransport::WriteResponseSilently (uint32_t resp_msg_id, uint32_t req_id, const std::vector<uint8_t >& body) {
979+ try {
980+ auto frame = protocol::NewMessage (resp_msg_id, req_id, body);
981+ std::vector<uint8_t > wrapped (4 + frame.size ());
982+ wrapped[0 ] = static_cast <uint8_t >((frame.size () >> 24 ) & 0xFF );
983+ wrapped[1 ] = static_cast <uint8_t >((frame.size () >> 16 ) & 0xFF );
984+ wrapped[2 ] = static_cast <uint8_t >((frame.size () >> 8 ) & 0xFF );
985+ wrapped[3 ] = static_cast <uint8_t >(frame.size () & 0xFF );
986+ std::memcpy (wrapped.data () + 4 , frame.data (), frame.size ());
987+ ssize_t sent = send (socket_, reinterpret_cast <const char *>(wrapped.data ()),
988+ static_cast <int >(wrapped.size ()), 0 );
989+ (void )sent;
990+ } catch (...) {
991+ // best-effort
992+ }
993+ }
994+
911995} // namespace sdk
912996} // namespace croupier
0 commit comments