baidu / sofa-pbrpc

A light-weight RPC implement of google protobuf RPC framework.
Other
2.13k stars 655 forks source link

RpcClient::Shutdown() 后,继续发送异步rpc请求,框架会挂掉 #200

Open bymzy opened 7 years ago

bymzy commented 7 years ago

再使用过程中碰到一种异常情况,调用Shutdown尝试关闭了rpc,但是后续又调用了异步的rpc请求。Shutdown 后会关闭连接,停掉回调线程组,清理线程组。后面调用异步请求后,判断RpcClient已经关闭,直接调用cntl->Done,但是任然使用rpc_impl的回掉线程组执行回掉,结果就是框架崩溃。

qinzuoyan commented 7 years ago

是否能把重现问题的sample code发一份出来?

cyshi commented 7 years ago

RpcClient::Shutdown()之后发起异步调用,但是开始回调后SimpleRpcChannelImpl::DoneCallback内获取回调线程组(_client_impl->GetCallbackThreadGroup()->post(done);)的时候指针已经被释放了,所以coredump,是这个意思么?

bymzy commented 7 years ago

` int main() { SOFA_PBRPC_SET_LOG_LEVEL(NOTICE);

 // Define an rpc server.
 sofa::pbrpc::RpcClientOptions client_options;
 sofa::pbrpc::RpcClient rpc_client(client_options);

 // Define an rpc channel.
 sofa::pbrpc::RpcChannelOptions channel_options;
 sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, "127.0.0.1:12321", channel_options);

 rpc_client.Shutdown();
 // Prepare parameters.
 sofa::pbrpc::RpcController* cntl = new sofa::pbrpc::RpcController();
 cntl->SetTimeout(3000);
 sofa::pbrpc::test::EchoRequest* request = new sofa::pbrpc::test::EchoRequest();
 request->set_message("Hello from qinzuoyan01");
 sofa::pbrpc::test::EchoResponse* response = new sofa::pbrpc::test::EchoResponse();
 bool callbacked = false;
 google::protobuf::Closure* done = sofa::pbrpc::NewClosure(
         &EchoCallback, cntl, request, response, &callbacked);

 // Async call.
 sofa::pbrpc::test::EchoServer_Stub stub(&rpc_channel);
 stub.Echo(cntl, request, response, done);

 // Wait call done.
 while (!callbacked) {
     usleep(100000);
 }

 return EXIT_SUCCESS;

} ` 以sample中的client_async.cc 为里,main函数中加入rpc_client.Shutdown()执行后就能复现。

bymzy commented 7 years ago

@cyshi 是的

cyshi commented 7 years ago

这个我觉得有点像指针delete后,又去访问,应该用户控制。 @qinzuoyan 看看。 另外 @bymzy 是有什么场景必须这么用么?

bymzy commented 7 years ago
  1. 没有必须要这样用的场景,我们的使用是有问题的(RpcClient已经stop的情况下,不应该再发送rpc请求)。
  2. 但是就sofa-rpc框架而言,是否应该对这种异常提供一种比较好的处理方式?