| 570 | } |
| 571 | |
| 572 | void ProcessThriftResponse(InputMessageBase* msg_base) { |
| 573 | const int64_t start_parse_us = butil::cpuwide_time_us(); |
| 574 | DestroyingPtr<MostCommonMessage> msg(static_cast<MostCommonMessage*>(msg_base)); |
| 575 | |
| 576 | // Fetch correlation id that we saved before in `PacThriftRequest' |
| 577 | const CallId cid = { static_cast<uint64_t>(msg->socket()->correlation_id()) }; |
| 578 | Controller* cntl = NULL; |
| 579 | const int rc = bthread_id_lock(cid, (void**)&cntl); |
| 580 | if (rc != 0) { |
| 581 | LOG_IF(ERROR, rc != EINVAL && rc != EPERM) |
| 582 | << "Fail to lock correlation_id=" << cid << ": " << berror(rc); |
| 583 | return; |
| 584 | } |
| 585 | |
| 586 | ControllerPrivateAccessor accessor(cntl); |
| 587 | if (auto span = accessor.span()) { |
| 588 | span->set_base_real_us(msg->base_real_us()); |
| 589 | span->set_received_us(msg->received_us()); |
| 590 | span->set_response_size(msg->payload.length()); |
| 591 | span->set_start_parse_us(start_parse_us); |
| 592 | } |
| 593 | |
| 594 | const int saved_error = cntl->ErrorCode(); |
| 595 | do { |
| 596 | // The following code was taken from thrift auto generate code |
| 597 | std::string fname; |
| 598 | ::apache::thrift::protocol::TMessageType mtype; |
| 599 | uint32_t seq_id = 0; // unchecked |
| 600 | |
| 601 | butil::Status st = ReadThriftMessageBegin(&msg->payload, &fname, &mtype, &seq_id); |
| 602 | if (!st.ok()) { |
| 603 | cntl->SetFailed(ERESPONSE, "%s", st.error_cstr()); |
| 604 | break; |
| 605 | } |
| 606 | if (mtype == ::apache::thrift::protocol::T_EXCEPTION) { |
| 607 | ::apache::thrift::TApplicationException x; |
| 608 | ReadThriftException(msg->payload, &x); |
| 609 | // TODO: Convert exception type to brpc errors. |
| 610 | cntl->SetFailed(x.what()); |
| 611 | break; |
| 612 | } |
| 613 | if (mtype != ::apache::thrift::protocol::T_REPLY) { |
| 614 | cntl->SetFailed(ERESPONSE, "message_type is not T_REPLY"); |
| 615 | break; |
| 616 | } |
| 617 | if (fname != cntl->thrift_method_name()) { |
| 618 | cntl->SetFailed(ERESPONSE, |
| 619 | "response.method_name=%s does not match request.method_name=%s", |
| 620 | fname.c_str(), cntl->thrift_method_name().c_str()); |
| 621 | break; |
| 622 | } |
| 623 | |
| 624 | // Read presult |
| 625 | |
| 626 | // MUST be ThriftFramedMessage (checked in SerializeThriftRequest) |
| 627 | ThriftFramedMessage* response = (ThriftFramedMessage*)cntl->response(); |
| 628 | if (response) { |
| 629 | if (response->raw_instance()) { |
nothing calls this directly
no test coverage detected