使用请求来验证命令是否成功

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,它没有任何用处。 :)