TarsCloud / TarsCpp

C++ language framework rpc source code implementation
BSD 3-Clause "New" or "Revised" License
520 stars 254 forks source link

请问一下如何让同一个Application中的RPC调用返回callback处理和作为服务器端响应客户端RPC请求处理在同一个进程中 #247

Closed xiaodoudou12 closed 2 years ago

xiaodoudou12 commented 2 years ago

image 作为server端响应RPC请求我看是从上图所示调用过去。 image 作为client端处理RPC返回callback我看堆栈如上图所示。 这两处逻辑运行在不同的进程下。 我看TC_EpollServer::Handle::handleOnceThread中的注释也提到主逻辑单线程化。 image ServantCallback可以实现onDispatch的的时候加入缓冲队列,然后让主线程处理 image 注释上说业务自有的callback需要从ServantCallback继承,但是使用.tars文件自动生成的代码都是继承自ServantProxyCallback而且已经完成生成onDispatch实现。 请教一下是不是我使用的方法不对,应该用其他方法实现逻辑单线程化。 image 我的测试方法如上,收到一个RPC请求,向另一个测试节点发起异步请求,处理回调结果,期望能把两处逻辑运行在同一个线程中实现单线程化。试了一下promise和coro方式调用,后续都会阻塞当前请求等待结果返回。 请问一下有没有既是S又是C的模型下实现主逻辑单线程化的示例程序。还是因为我上面使用的方法不对,请指教,多谢。

ruanshudong commented 2 years ago

框架里面是有个用法, 具体使用方式如下: 1 你的callback继承ServantCallback 2 在GateImp中增加函数: /**

处理实际的第一步的callback msg, 能达到你说的效果, 但是这个模式基本没怎么推广了, 有点复杂, 难以理解.

你为啥不直接用协程来完成呢? 这样也是异步的, 也都在同一个imp线程里面完成

xiaodoudou12 commented 2 years ago

CoroParallelBasePtr sharedPtr = new CoroParallelBase(1);
GameCoroPrxCallbackPtr cb2 = new HelloCoroCallBack(); cb2->setCoroParallelBasePtr(sharedPtr); game_prx->coro_testHello(cb2, sReq_1); coroWhenAll(sharedPtr);

协程模式我也有尝试,coroWhenAll应该会阻塞当前imp等待上面协程完成处理,感觉在等待期间的话主逻辑的ServantHandle应该还可以响应其他的RPC请求,相当于每一个RPC请求都是运行在一个独立的协程下面,所有的协程都运行在主逻辑线程上实现单线程化。 不知道我的理解对不对。

ruanshudong commented 2 years ago

你这个理解基本对, coroWhenAll时, imp线程会响应其他请求的, 并不会阻塞请求的 串行模式可以参考examples的 BServantImp::testCoroSerial, 调用rpc的时候也不会阻塞其他请求的, 核心注意在配置里面设置:

opencoroutine

    opencoroutine = 1

当然协程模式有几种, 具体可以参考文档

ruanshudong commented 2 years ago

每个请求相当于一个协程了, 等待过程中就释放了, imp会启动其他协程处理其他请求, 等上一个请求响应回来, 又会唤醒, 大概就是这样的逻辑

xiaodoudou12 commented 2 years ago

懂了,多谢大佬