我有一个grpc异步服务器:一个具有多线程的完整队列。 它将以如下输出为核心:
E0717 18:54:02.635424482 14110 server_cc.cc:677] Fatal: grpc_call_start_batch returned 8 E0717 18:54:02.635514690 14110 server_cc.cc:678] ops[0]: SEND_MESSAGE ptr=0x7f3c0815cb60 E0717 18:54:02.635563281 14110 server_cc.cc:678] ops[1]: SEND_STATUS_FROM_SERVER status=0
当我仅使用一个线程时,它运行良好。如果线程数少,则服务器可以运行更长的时间。
class BaseCallData {
public:
BaseCallData(XFRProcessor *processor)
: processor_(processor), status_(CallStatus::CREATE) {}
virtual ~BaseCallData() = default;
void Proceed() {
if (status_ == CallStatus::CREATE) {
status_ = CallStatus::PROCESS;
Request();
} else if (status_ == CallStatus::PROCESS) {
NewCallData();
//TODO
OnRequest();
Response();
status_ = CallStatus::FINISH;
} else if (status_ == CallStatus::FINISH) {
req_timer_.timer_->SetSelfEnd("delete");
delete this;
} else {
LOGGER_ERROR(Log::GetLog(), "wrong grpc status");
}
}
protected:
std::unique_ptr<PrometheusMetricsWrapper> prometheus_metrics_;
private:
...
enum class CallStatus { CREATE, PROCESS, FINISH };
CallStatus status_;
};
class DetectCallData : public BaseCallData {
public:
DetectCallData(::xfr::XFRService::AsyncService *service, ServerCompletionQueue *cq, XFRProcessor *processor)
: BaseCallData(processor), p_service_(service), p_cq_(cq), responder_(&ctx_) {
Proceed();
}
void NewCallData() override {
new DetectCallData(p_service_, p_cq_, GetProcessor());
}
void Request() override {
p_service_->RequestDetect(&ctx_, &request_, &responder_, p_cq_, p_cq_, this);
}
void Response() override {
responder_.Finish(response_, Status::OK, this);
}
void OnRequest() override {
//process
}
private:
ServerContext ctx_;
::xfr::XFRService::AsyncService *p_service_;
ServerCompletionQueue *p_cq_;
::xfr::DetectRequest request_;
::xfr::DetectResponse response_;
...
ServerAsyncResponseWriter<::xfr::DetectResponse> responder_;
};
class XFRServer final {
public:
XFRServer(const XFRServer &) = delete;
XFRServer &operator=(const XFRServer &) = delete;
XFRServer() {
Init();
builder_.AddListeningPort(address_, InsecureServerCredentials());
builder_.RegisterService(&service_);
cq_ = builder_.AddCompletionQueue();
}
void Init() {
...
}
~XFRServer() {
server_->Shutdown();
//document shows that cq should always shutdown after server
cq_->Shutdown();
}
void HandleRpcs(ServerCompletionQueue *cq) {
new DetectCallData(&service_, cq, detect_processor.get());
void *tag{nullptr};
bool ok{false};
while (true) {
if (!cq->Next(&tag, &ok)) {
LOGGER_WARN(Log::GetLog(), "Server stream closed");
break;
}
static_cast<BaseCallData *>(tag)->Proceed();
if(!ok){
LOGGER_WARN(Log::GetLog(),"status wrong when tag out from complete queue");
}
}
}
void run() {
server_ = builder_.BuildAndStart();
for (int i=0; i<100; i++) {//!!!!!when set 100 to 1, it works well
v_threads_.emplace_back(
std::thread([this] {
HandleRpcs(cq_.get());
})
);
}
LOGGER_INFO(Log::GetLog(), "grpc server start working...");
for (auto &t: v_threads_) {
t.join();
}
}
private:
...
};
} //namespace grpc
} // namespace xfr
} // namespace vision
} // namespace hobot
#endif //XFR_GRPCSERVER_H
有人可以告诉我如何构建具有多线程的异步服务器吗? 我的代码有什么问题?