| 305 | } |
| 306 | |
| 307 | int Sender::IssueRPC(int64_t start_realtime_us) { |
| 308 | _main_cntl->_current_call.need_feedback = false; |
| 309 | LoadBalancer::SelectIn sel_in = { start_realtime_us, |
| 310 | true, |
| 311 | _main_cntl->has_request_code(), |
| 312 | _main_cntl->_request_code, |
| 313 | _main_cntl->_accessed }; |
| 314 | ChannelBalancer::SelectOut sel_out; |
| 315 | const int rc = static_cast<ChannelBalancer*>(_main_cntl->_lb.get()) |
| 316 | ->SelectChannel(sel_in, &sel_out); |
| 317 | if (rc != 0) { |
| 318 | _main_cntl->SetFailed(rc, "Fail to select channel, %s", berror(rc)); |
| 319 | return -1; |
| 320 | } |
| 321 | _main_cntl->_current_call.need_feedback = sel_out.need_feedback; |
| 322 | _main_cntl->_current_call.peer_id = sel_out.fake_sock->id(); |
| 323 | |
| 324 | Resource r = PopFree(); |
| 325 | if (r.sub_done == NULL) { |
| 326 | CHECK(false) << "Impossible!"; |
| 327 | _main_cntl->SetFailed("Impossible happens"); |
| 328 | return -1; |
| 329 | } |
| 330 | r.sub_done->_cid = _main_cntl->current_id(); |
| 331 | r.sub_done->_peer_id = sel_out.fake_sock->id(); |
| 332 | Controller* sub_cntl = &r.sub_done->_cntl; |
| 333 | // No need to count timeout. We already managed timeout in schan. If |
| 334 | // timeout occurs, sub calls are canceled with ERPCTIMEDOUT. |
| 335 | sub_cntl->_timeout_ms = -1; |
| 336 | sub_cntl->_real_timeout_ms = _main_cntl->timeout_ms(); |
| 337 | |
| 338 | // Inherit following fields of _main_cntl. |
| 339 | // TODO(gejun): figure out a better way to maintain these fields. |
| 340 | sub_cntl->set_connection_type(_main_cntl->connection_type()); |
| 341 | sub_cntl->set_type_of_service(_main_cntl->_tos); |
| 342 | sub_cntl->set_request_compress_type(_main_cntl->request_compress_type()); |
| 343 | sub_cntl->set_log_id(_main_cntl->log_id()); |
| 344 | sub_cntl->set_request_code(_main_cntl->request_code()); |
| 345 | // Forward request attachment to the subcall |
| 346 | sub_cntl->request_attachment().append(_main_cntl->request_attachment()); |
| 347 | ProtocolType protocol = _main_cntl->request_protocol(); |
| 348 | if (PROTOCOL_HTTP == protocol || PROTOCOL_H2 == protocol) { |
| 349 | sub_cntl->http_request() = _main_cntl->http_request(); |
| 350 | } |
| 351 | |
| 352 | sel_out.channel()->CallMethod(_main_cntl->_method, &r.sub_done->_cntl, |
| 353 | _request, r.response, r.sub_done); |
| 354 | return 0; |
| 355 | } |
| 356 | |
| 357 | void SubDone::Run() { |
| 358 | Controller* main_cntl = NULL; |
nothing calls this directly
no test coverage detected