| 74 | }; |
| 75 | |
| 76 | int main(int argc, const char** argv) |
| 77 | { |
| 78 | const char* port = argc >= 2 ? argv[1] : "50051"; |
| 79 | const auto host = std::string("localhost:") + port; |
| 80 | const auto thread_count = std::thread::hardware_concurrency(); |
| 81 | |
| 82 | helloworld::Greeter::Stub stub{grpc::CreateChannel(host, grpc::InsecureChannelCredentials())}; |
| 83 | std::vector<std::unique_ptr<GuardedGrpcContext>> grpc_contexts; |
| 84 | |
| 85 | // Create GrpcContexts and their work guards. |
| 86 | for (size_t i = 0; i < thread_count; ++i) |
| 87 | { |
| 88 | grpc_contexts.emplace_back(std::make_unique<GuardedGrpcContext>()); |
| 89 | } |
| 90 | |
| 91 | // Create one thread per GrpcContext. |
| 92 | std::vector<std::thread> threads; |
| 93 | threads.reserve(thread_count); |
| 94 | for (size_t i = 0; i < thread_count; ++i) |
| 95 | { |
| 96 | threads.emplace_back( |
| 97 | [&, i] |
| 98 | { |
| 99 | grpc_contexts[i]->context.run(); |
| 100 | }); |
| 101 | } |
| 102 | |
| 103 | // Make some example requests. |
| 104 | RoundRobin round_robin_grpc_contexts{grpc_contexts.begin(), thread_count}; |
| 105 | for (size_t i{}; i < 20; ++i) |
| 106 | { |
| 107 | auto& grpc_context = round_robin_grpc_contexts.next()->context; |
| 108 | asio::co_spawn(grpc_context, make_request(grpc_context, stub), example::RethrowFirstArg{}); |
| 109 | } |
| 110 | |
| 111 | for (auto& grpc_context : grpc_contexts) |
| 112 | { |
| 113 | grpc_context->guard.reset(); |
| 114 | } |
| 115 | |
| 116 | for (auto& thread : threads) |
| 117 | { |
| 118 | thread.join(); |
| 119 | } |
| 120 | } |