Reorder code to set num_frequently_polled_cqs correctly.

When there num_frequently_polled_cqs is non-zero (aka hybrid server),
we create non-polling CQs for the sync methods. But, since we
increase num_frequently_polled_cqs for callback methods
after creating the sync CQs, the sync CQs would not detect
a hyprid server, and will create a polling CQ.

This commit reorders the logic, so that we increment
num_frequently_polled_cqs upon detecting a callback service.

This lowers the context switches by double digit percentage
when using callback API.
pull/18025/head
Soheil Hassas Yeganeh 6 years ago
parent 20ab15a3f2
commit 37c1f0bd54
  1. 32
      src/cpp/server/server_builder.cc

@ -243,15 +243,25 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
sync_server_cqs(std::make_shared<
std::vector<std::unique_ptr<ServerCompletionQueue>>>());
int num_frequently_polled_cqs = 0;
bool has_frequently_polled_cqs = false;
for (auto it = cqs_.begin(); it != cqs_.end(); ++it) {
if ((*it)->IsFrequentlyPolled()) {
num_frequently_polled_cqs++;
has_frequently_polled_cqs = true;
break;
}
}
// == Determine if the server has any callback methods ==
bool has_callback_methods = false;
for (auto it = services_.begin(); it != services_.end(); ++it) {
if ((*it)->service->has_callback_methods()) {
has_callback_methods = true;
has_frequently_polled_cqs = true;
break;
}
}
const bool is_hybrid_server =
has_sync_methods && num_frequently_polled_cqs > 0;
const bool is_hybrid_server = has_sync_methods && has_frequently_polled_cqs;
if (has_sync_methods) {
grpc_cq_polling_type polling_type =
@ -264,15 +274,6 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
}
}
// == Determine if the server has any callback methods ==
bool has_callback_methods = false;
for (auto it = services_.begin(); it != services_.end(); ++it) {
if ((*it)->service->has_callback_methods()) {
has_callback_methods = true;
break;
}
}
// TODO(vjpai): Add a section here for plugins once they can support callback
// methods
@ -306,13 +307,12 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
for (auto it = sync_server_cqs->begin(); it != sync_server_cqs->end(); ++it) {
grpc_server_register_completion_queue(server->server_, (*it)->cq(),
nullptr);
num_frequently_polled_cqs++;
has_frequently_polled_cqs = true;
}
if (has_callback_methods) {
auto* cq = server->CallbackCQ();
grpc_server_register_completion_queue(server->server_, cq->cq(), nullptr);
num_frequently_polled_cqs++;
}
// cqs_ contains the completion queue added by calling the ServerBuilder's
@ -325,7 +325,7 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
nullptr);
}
if (num_frequently_polled_cqs == 0) {
if (!has_frequently_polled_cqs) {
gpr_log(GPR_ERROR,
"At least one of the completion queues must be frequently polled");
return nullptr;

Loading…
Cancel
Save