rotor is an unobtrusive C ++ actor microformwork with the ability to create supervisor hierarchies, similar to its older brothers - caf and sobjectizer . In recent releases, since the last announcement , significant improvements have accumulated that I would like to highlight.
Common interface for timers (v0.10)
, . . . v0.10
API , ; (event loop) API, . : API , API rotor', . , , .
v0.10
rotor', - :
namespace r = rotor;
struct some_actor_t: r::actor_base_t {
void on_start() noexcept {
timer_request = start_timer(timeout, *this, &some_actor_t::on_timer);
}
void on_timer(r::request_id_t, bool cancelled) noexcept {
...;
}
void some_method() noexcept {
...
cancel_timer(timer_id);
}
r::request_id_t timer_id;
};
, (shutdown_finish), , (undefined behavior).
(v0.10)
- , caf "-", sobjectizer' "--" ("fire-and-forget") . rotor , - "--", "-" .
, caf sobjectizer, , , , . , rotor' , , . "-" , "" , - (I/O), . , HTTP-, , . : , , , .
, , .. - , , - .
rotor', , , , - , , , , -, , , "". , - , . . .
namespace r = rotor;
namespace payload {
struct pong_t {};
struct ping_t {
using response_t = pong_t;
};
} // namespace payload
namespace message {
using ping_request_t = r::request_traits_t<payload::ping_t>::request::message_t;
using ping_response_t = r::request_traits_t<payload::ping_t>::response::message_t;
using ping_cancel_t = r::request_traits_t<payload::ping_t>::cancel::message_t;
} // namespace message
struct some_actor_t: r::actor_base_t {
using ping_ptr_t = r::intrusive_ptr_t<message::ping_request_t>;
void on_ping(ping_request_t& req) noexcept {
// just store request for further processing
ping_req.reset(&req);
}
void on_cancel(ping_cancel_t&) noexcept {
if (req) {
// make_error is v0.14 feature
make_response(*req, make_error(r::make_error_code(r::error_code_t::cancelled)));
req.reset();
}
}
// "" .
ping_ptr_t ping_req;
};
, sobjectizer', , , -, "-", , -, , sobjectizer', . . . , - , "-" sobjectizer', , , , , .
std::thread backend/supervisor (v0.12)
, rotor sobjectizer: , . , .
, . , , . , ; , , , . , , , .. , , sha512 1TB, , . .
, std::thread
, . , , , rotor' , "" (), . , ..:
struct sha_actor_t : public r::actor_base_t {
...
void configure(r::plugin::plugin_base_t &plugin) noexcept override {
r::actor_base_t::configure(plugin);
plugin.with_casted<r::plugin::starter_plugin_t>([&](auto &p) {
p.subscribe_actor(&sha_actor_t::on_process)->tag_io(); //
});
}
(v0.14)
— ( rotor' , sobjectizer' mbox
'). , , , :
struct my_supervisor_t : public r::supervisor_t {
void on_child_shutdown(actor_base_t *actor) noexcept override {
std::cout << "actor " << (void*) actor->get_address().get() << " died \n";
}
}
, . , , , , on_start()
. , , std::string identity
actor_base_t
. , address_maker_plugin_t
:
struct some_actor_t : public t::actor_baset_t {
void configure(r::plugin::plugin_base_t &plugin) noexcept override {
plugin.with_casted<r::plugin::address_maker_plugin_t>([&](auto &p) {
p.set_identity("my-actor-name", false);
});
...
}
};
:
struct my_supervisor_t : public r::supervisor_t {
void on_child_shutdown(actor_base_t *actor) noexcept override {
std::cout << actor->get_identity() << " died \n";
}
}
, . , . bool
set_identity(name, append_addr)
.
- actor 0x7fd918016d70
supervisor 0x7fd218016d70
. rotor' v0.14
.
Extended Error std::error_code, shutdown reason (v0.14)
- , v0.14
, std::error_code
. , , , rotor', . : , . , . . . , , , , , . , std::error_code
.
Therefore, it was decided to introduce our own extended error class rotor::extended_error_t
, which contains std::error_code
, std::string
as a context (usually the identity of the actor), as well as a smart pointer to the next extended error that caused the current one. Now the collapse of the actor hierarchy can be represented by a chain of extended errors, where the reason for the shutdown of each actor can be traced:
struct my_supervisor_t : public r::supervisor_t {
void on_child_shutdown(actor_base_t *actor) noexcept override {
std::cout << actor->get_identity() << " died, reason :: " << actor->get_shutdown_reason()->message();
}
}
will output something like:
actor-2 due to supervisor shutdown has been requested by supervisor <- actor-1 due initialization failed
Together with actor identification, this feature provides more diagnostic tools for developers who use rotor .