使用请求来验证命令是否成功
Using requests to verify command success
假设Typed Actor A需要命令Typed Actor B做某事。 Actor A 还需要知道命令 运行 是否成功,但不想在响应到达之前阻止操作。我目前的工作理论是,这个最好满足Requests。更具体地说 request(...).then
有一个很好的例子叫做“request.cpp”,我一直在玩这个例子。我的挑战是我真的不需要演员 B return 任何数据。我只需要知道命令是否成功,如果不成功,抛出了什么错误。
所以我的问题有两个:1) 我认为 request(...).then
是做我想做的事情的正确机制是否正确,以及 2) 如果是这样,那么请求是否可以处理没有数据的响应?
这就是我正在尝试的:
#include <chrono>
#include <cstdint>
#include <iostream>
#include <vector>
#include "caf/all.hpp"
using std::endl;
using std::vector;
using std::chrono::seconds;
using namespace caf;
using cell
= typed_actor<result<void>(get_atom, int32_t)>;
struct cell_state {
static constexpr inline const char* name = "cell";
cell::pointer self;
cell_state(cell::pointer ptr) : self(ptr) {}
cell_state(const cell_state&) = delete;
cell_state& operator=(const cell_state&) = delete;
cell::behavior_type make_behavior() {
return {
[=](get_atom, int32_t input) -> result<void> {
if (input != 5) { // Simulate command successful or not
return; // If successful, then return;
}
else {
return sec::unexpected_message; // If not then return error.
}
},
};
}
};
using cell_impl = cell::stateful_impl<cell_state>;
void multiplexed_testee(event_based_actor* self, vector<cell> cells) {
for (cell& x : cells) {
aout(self) << "cell #" << x.id() << " calling" << endl;
self->request(x, seconds(1), get_atom_v, static_cast<int32_t>(x.id()))
.then(
[=](void) {
aout(self) << "cell #" << x.id() << " -> " << "success" << endl;
},
[=](error& err) {
aout(self) << "cell #" << x.id() << " -> " << to_string(err) << endl;
});
}
}
void caf_main(actor_system& system) {
vector<cell> cells;
for (int32_t i = 0; i < 5; ++i)
cells.emplace_back(system.spawn<cell_impl>());
scoped_actor self{ system };
auto x2 = self->spawn(multiplexed_testee, cells);
self->wait_for(x2);
}
CAF_MAIN()
当我编译时,我在空的 return 语句上得到一个错误,说“return-statement with no value, in function returning caf::result<void>
”。是有更好的方法吗?
我的备份计划是将我的命令定义更改为 return 标准错误和 return sec::none
如果操作成功。但恐怕这种方法违反了错误条件的整个可选第二参数的精神。我对这一切的看法如何?
Is there a better way to do this?
你的想法是对的。 result<void>
需要错误或 'void' 值。因为 void{}
在 C++ 中不是一个东西,你可以做 return caf::unit;
告诉 result<void>
构造一个“空”结果。在接收方方面,您已经做了正确的事情:then
使用不带参数的 lambda。
要点:
[=](void) { ... }
这是早期的 C-ism,编译器允许您做一些愚蠢的事情。只需删除 void
,它没有任何用处。 :)
假设Typed Actor A需要命令Typed Actor B做某事。 Actor A 还需要知道命令 运行 是否成功,但不想在响应到达之前阻止操作。我目前的工作理论是,这个最好满足Requests。更具体地说 request(...).then
有一个很好的例子叫做“request.cpp”,我一直在玩这个例子。我的挑战是我真的不需要演员 B return 任何数据。我只需要知道命令是否成功,如果不成功,抛出了什么错误。
所以我的问题有两个:1) 我认为 request(...).then
是做我想做的事情的正确机制是否正确,以及 2) 如果是这样,那么请求是否可以处理没有数据的响应?
这就是我正在尝试的:
#include <chrono>
#include <cstdint>
#include <iostream>
#include <vector>
#include "caf/all.hpp"
using std::endl;
using std::vector;
using std::chrono::seconds;
using namespace caf;
using cell
= typed_actor<result<void>(get_atom, int32_t)>;
struct cell_state {
static constexpr inline const char* name = "cell";
cell::pointer self;
cell_state(cell::pointer ptr) : self(ptr) {}
cell_state(const cell_state&) = delete;
cell_state& operator=(const cell_state&) = delete;
cell::behavior_type make_behavior() {
return {
[=](get_atom, int32_t input) -> result<void> {
if (input != 5) { // Simulate command successful or not
return; // If successful, then return;
}
else {
return sec::unexpected_message; // If not then return error.
}
},
};
}
};
using cell_impl = cell::stateful_impl<cell_state>;
void multiplexed_testee(event_based_actor* self, vector<cell> cells) {
for (cell& x : cells) {
aout(self) << "cell #" << x.id() << " calling" << endl;
self->request(x, seconds(1), get_atom_v, static_cast<int32_t>(x.id()))
.then(
[=](void) {
aout(self) << "cell #" << x.id() << " -> " << "success" << endl;
},
[=](error& err) {
aout(self) << "cell #" << x.id() << " -> " << to_string(err) << endl;
});
}
}
void caf_main(actor_system& system) {
vector<cell> cells;
for (int32_t i = 0; i < 5; ++i)
cells.emplace_back(system.spawn<cell_impl>());
scoped_actor self{ system };
auto x2 = self->spawn(multiplexed_testee, cells);
self->wait_for(x2);
}
CAF_MAIN()
当我编译时,我在空的 return 语句上得到一个错误,说“return-statement with no value, in function returning caf::result<void>
”。是有更好的方法吗?
我的备份计划是将我的命令定义更改为 return 标准错误和 return sec::none
如果操作成功。但恐怕这种方法违反了错误条件的整个可选第二参数的精神。我对这一切的看法如何?
Is there a better way to do this?
你的想法是对的。 result<void>
需要错误或 'void' 值。因为 void{}
在 C++ 中不是一个东西,你可以做 return caf::unit;
告诉 result<void>
构造一个“空”结果。在接收方方面,您已经做了正确的事情:then
使用不带参数的 lambda。
要点:
[=](void) { ... }
这是早期的 C-ism,编译器允许您做一些愚蠢的事情。只需删除 void
,它没有任何用处。 :)