Capnproto - 在服务器回调中发出客户端请求
Capnproto - Make client request in server callback
我需要在服务器回调中执行一些客户端请求,并且不确定将创建的capnp::EzRpcClient
和CompareNetwork::Client comparer
对象存储在哪里。那是因为客户端超出了范围(我认为 - 我只是得到了一个 SEGFAULT,但这似乎是原因(。它基本上是一个将加载请求转发给其从属服务器的主站(从站可以通过 REG 请求注册并存储它们的地址(。
那么 - 我应该在哪里/如何存储客户端对象?这有什么"最佳实践"吗?我认为将它们临时存储在某个类成员变量中有点脏,不是吗?
组大师2.cpp:
kj::Promise<void> GroupMaster2::CompareMasterImpl::load(LoadContext context) {
auto loadData = context.getParams().getIds();
slaveListLock.lock();
auto promList = kj::Vector<kj::Promise<std::pair<std::string, CompareNetwork::Status>>>();
for(auto& slave : slaveList) {
try {
capnp::EzRpcClient client(slave.second->address);
CompareNetwork::Client comparer = client.getMain<CompareNetwork>();
auto request = comparer.loadRequest();
std::string addrCopy(slave.first);
request.setIds(loadData);
auto loadPromise = request.send();
promList.add(loadPromise.then([addrCopy](auto response) {
return std::make_pair(addrCopy, response.getStatus());
},
[&, addrCopy](kj::Exception && exception) {
slaveListLock.lock();
slaveList.erase(addrCopy);//something failed, remove this slave!
slaveListLock.unlock();
std::cout << "ErrLoad0: " << std::string(exception.getDescription()) << std::endl;
return std::make_pair(addrCopy, CompareNetwork::Status::ERROR);
}));
}
catch(...) {
std::cout << "Error sending load to: " << slave.first << std::endl;
}
}
slaveListLock.unlock();
auto retProm = kj::joinPromises(promList.releaseAsArray()).then([&, KJ_CPCAP(context)](kj::Array<std::pair<std::string, CompareNetwork::Status>> res) mutable {
bool error = false;
for(auto& loadRes : res) {
switch(loadRes.second) {
case CompareNetwork::Status::OK: {
std::cout << "LOAD OK: " << loadRes.first << std::endl;
break;
}
case CompareNetwork::Status::ERROR: {
std::cout << "LOAD ERROR: " << loadRes.first << std::endl;
error = true;
break;
}
}
}
if(!error)
context.getResults().setStatus(CompareNetwork::Status::OK);
else
context.getResults().setStatus(CompareNetwork::Status::ERROR);
}, [](kj::Exception && exception) {
std::cout << __FILE__ << ":" << __LINE__ << std::string(exception.getDescription()) << std::endl;
}).eagerlyEvaluate([](kj::Exception && exception) {
std::cout << __FILE__ << ":" << __LINE__ << std::string(exception.getDescription()) << std::endl;
});
std::cout << "ReturnedLoad" << std::endl;
return retProm;
}
GroupNetworkData.capnp:
interface CompareNetwork {
compare @0 (jobs :JobPartList) -> (res :JobResList);
load @1 (ids :WIDList) -> (status :Status);
struct JobPartList {
jobParts @0 :List(JobPart);
struct JobPart {
jobs @0 :List(Job);
startID @1 :UInt32;
struct Job {
wid1 @0 :UInt32;
wid2 @1 :UInt32;
}
}
}
struct JobResList {
jobResults @0 :List(JobRes);
struct JobRes {
jobIndex @0 :UInt32;
result @1 :Float64;
}
}
struct WIDList {
ids @0 :List(WID);
struct WID {
id @0 :UInt32;
}
}
enum Status {
ok @0;
error @1;
}
}
interface CompareMaster extends(CompareNetwork) {
reg @0 (data :SlaveData) -> (status :CompareNetwork.Status);
struct SlaveData {
perfInd @0 :Float64;
maxMem @1 :UInt32;
address @2 :Text;
}
}
提前感谢!DVS23
C++14 似乎有答案:
如何将unique_ptr捕获到 lambda 表达式中?
使用 kj::heap 在堆上分配两个对象,并将 kj::Own 移动到回调 lambda:
for(auto& slave : slaveList) {
try {
auto client = kj::heap<capnp::EzRpcClient>(slave.second->address);
auto comparer = kj::heap<CompareNetwork::Client>(client->getMain<CompareNetwork>());
auto request = comparer->loadRequest();
std::string addrCopy(slave.first);
request.setIds(loadData);
auto loadPromise = request.send();
promList.add(loadPromise.then([addrCopy, client = std::move(client), comparer = std::move(comparer)](auto response) {
return std::make_pair(addrCopy, response.getStatus());
},
[&, addrCopy](kj::Exception && exception) {
slaveListLock.lock();
slaveList.erase(addrCopy);//something failed, remove this slave!
slaveListLock.unlock();
std::cout << "ErrLoad0: " << std::string(exception.getDescription()) << std::endl;
return std::make_pair(addrCopy, CompareNetwork::Status::ERROR);
}));
}
catch(...) {
std::cout << "Error sending load to: " << slave.first << std::endl;
}
}
欢迎更好的想法,但目前它似乎工作得很好:)
相关文章:
- 节点.js HTTP 无法通过套接字接收来自C++客户端的请求
- C++HTTP客户端在GET请求后挂起read()调用
- 如何将请求的客户端连接的 IP 与 QTcpSocket 类中识别的 IP 之一进行比较?
- 如何在函数内部使用 zmq(以非阻塞方式)在客户端请求时获取函数的状态?
- Capnproto - 在服务器回调中发出客户端请求
- 异步WT :: HTTP ::客户端响应和请求匹配
- 如何在 gRPC 的异步C++客户端中为每个请求设置超时?
- 当发送多个同时请求时,单线程异步系统中Beast Boost异步HTTP客户端的行为
- 使用 select() 的请求/回复服务器。无法写回客户端
- 用于C++的Google API客户端库与用于发送HTTP请求的libcurl
- HTTP 请求使用 Google API 客户端库进行C++
- 如何使用套接字实现服务器客户端编程,在套接字中服务器向客户端发送消息而不从客户端获取请求
- Zeromq如何制作一个允许它不等待客户端请求的C ++服务器程序
- 如何从 http 请求中获取客户端 IP
- 客户端无法通过udp连接向服务器发送请求
- C服务器套接字接受没有请求的客户端
- 如何在一个套接字上实现并行请求和响应的非阻塞客户端-服务器通信模型,而不存在数据竞争
- 什么OOD设计模式应该用于服务器-处理-客户端请求
- HTTP 客户端请求响应与 pion-net c++
- FTP客户端请求失败