Reputation: 53
I'm trying to shutdown properly a gRPC server.
I use the provided async helloworld from gRPC source.
The file is here: https://github.com/grpc/grpc/blob/master/examples/cpp/helloworld/greeter_async_server.cc
I have edited the main like the following:
#include "greeter_async_server.cc"
#include <thread>
#include <iostream>
void stop_task(ServerImpl* server) {
int delay = 10000;
std::cout << "Server will stop after " << delay / 1000 << " seconds" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
std::cout << "Wait finished" << std::endl;
std::cout << "Stoping server..." << std::endl;
server->Shutdown();
std::cout << "Stop sent" << std::endl;
}
void server_task(ServerImpl* server) {
server->Run();
}
int main(int argc, char** argv) {
ServerImpl server;
std::thread server_thread(server_task, &server);
std::thread stop_thread(stop_task, &server);
stop_thread.join();
server_thread.join();
std::cout << "Server stopped" << std::endl;
return 0;
}
void ServerImpl::Shutdown()
{
server->Shutdown();
// Always shutdown the completion queue after the server.
cq->Shutdown();
}
Server will stop after 10 seconds
Server listening on 0.0.0.0:50051
Wait finished
Stoping server...
E0825 15:08:30.182000000 34960 greeter_async_server.cc:156] assertion failed: ok
Sortie de TestGreeterAsyncServer.exe (processus 37008). Code : -1073740791.
Appuyez sur une touche pour fermer cette fenêtre. . .
I don't understand why the server crashes on assertion failed. The assertion is at line 156:
GPR_ASSERT(ok);
Anyone has an idea?
Thank you in advance!
Upvotes: 0
Views: 1744
Reputation: 10486
You're trying to delete an object (server
) that's been created on the stack.
That said, the example code does not showcase any way to cleanly stop the server once it's been started. It is even said in a comment above the Run()
method:
There is no shutdown handling in this code.
This question provides good pointers on how to accomplish your goal.
Here is why the assertion is triggered:
cq_->Next(&tag, &ok);
is a blocking call, until either
ok == false
) ;ok == true
) ;cq_->Shutdown()
has been called (which also means ok == false
).You can read about all the different scenarios in CompletionQueue::Next()
documentation. Since you're shutting down, ok
is false
which triggers the assertion's failure.
Upvotes: 2
Reputation: 53
Here is the solution. I have edited the greeter_async_server.cc like this:
private:
// Adding attrbutes
bool is_shutting_down = false;
std::mutex mutex;
void HandleRpcs() {
new CallData(&service_, cq_.get());
void* tag;
bool ok;
while (true) {
GPR_ASSERT(cq_->Next(&tag, &ok));
// Here, added exit condition
mutex.lock();
if (true == is_shutting_down) {
mutex.unlock();
std::cout << "stop reading" << std::endl;
break;
}
else mutex.unlock();
GPR_ASSERT(ok);
static_cast<CallData*>(tag)->Proceed();
}
}
public:
// Adding Shutdown public method
void Shutdown() {
mutex.lock();
is_shutting_down = true;
mutex.unlock();
const std::chrono::milliseconds WaitDuration = std::chrono::milliseconds(50);
const std::chrono::time_point<std::chrono::system_clock> Deadline = std::chrono::system_clock::now() + WaitDuration;
server_->Shutdown(Deadline);
cq_->Shutdown();
}
Upvotes: 0