int Sender::IssueRPC(int64_t start_realtime_us) { _main_cntl->_current_call.need_feedback = false; LoadBalancer::SelectIn sel_in = { start_realtime_us, true, _main_cntl->has_request_code(), _main_cntl->_request_code, _main_cntl->_accessed }; ChannelBalancer::SelectOut sel_out; const int rc = static_cast<ChannelBalancer*>(_main_cntl->_lb.get()) ->SelectChannel(sel_in, &sel_out); if (rc != 0) { _main_cntl->SetFailed(rc, "Fail to select channel, %s", berror(rc)); return -1; } DLOG(INFO) << "Selected channel=" << sel_out.channel() << ", size=" << (_main_cntl->_accessed ? _main_cntl->_accessed->size() : 0); _main_cntl->_current_call.need_feedback = sel_out.need_feedback; _main_cntl->_current_call.peer_id = sel_out.fake_sock->id(); Resource r = PopFree(); if (r.sub_done == NULL) { CHECK(false) << "Impossible!"; _main_cntl->SetFailed("Impossible happens"); return -1; } r.sub_done->_cid = _main_cntl->current_id(); r.sub_done->_peer_id = sel_out.fake_sock->id(); Controller* sub_cntl = &r.sub_done->_cntl; // No need to count timeout. We already managed timeout in schan. If // timeout occurs, sub calls are canceled with ERPCTIMEDOUT. sub_cntl->_timeout_ms = -1; // Inherit following fields of _main_cntl. // TODO(gejun): figure out a better way to maintain these fields. sub_cntl->set_connection_type(_main_cntl->connection_type()); sub_cntl->set_type_of_service(_main_cntl->_tos); sub_cntl->set_request_compress_type(_main_cntl->request_compress_type()); sub_cntl->set_log_id(_main_cntl->log_id()); sub_cntl->set_request_code(_main_cntl->request_code()); // Forward request attachment to the subcall sub_cntl->request_attachment().append(_main_cntl->request_attachment()); sel_out.channel()->CallMethod(_main_cntl->_method, &r.sub_done->_cntl, _request, r.response, r.sub_done); return 0; }
//-------------------------------------------------------------------------------- void* CFreePool::Alloc() { return PopFree(); }