Commit 0c774e3e authored by Dominik Charousset's avatar Dominik Charousset

added priorities to delayed / timed messages

parent 31bcfc16
......@@ -314,7 +314,7 @@ class local_actor : public extend<actor>::with<memory_cached> {
void reply_message(any_tuple&& what);
void forward_message(const actor_ptr& new_receiver);
void forward_message(const actor_ptr& new_receiver, message_priority prio);
inline const actor_ptr& chained_actor();
......
......@@ -108,35 +108,26 @@ class scheduler {
virtual attachable* register_hidden_context();
template<typename Duration, typename... Data>
void delayed_send(const channel_ptr& to,
void delayed_send(message_header hdr,
const Duration& rel_time,
any_tuple data ) {
auto tup = make_any_tuple(atom("SEND"),
util::duration{rel_time},
to,
std::move(hdr),
std::move(data));
auto dsh = delayed_send_helper();
dsh->enqueue({self, dsh}, std::move(tup));
delayed_send_helper()->enqueue(nullptr, std::move(tup));
}
template<typename Duration, typename... Data>
void delayed_reply(const actor_ptr& to,
void delayed_reply(message_header hdr,
const Duration& rel_time,
message_id id,
any_tuple data ) {
CPPA_REQUIRE(!id.valid() || id.is_response());
if (id.valid()) {
auto tup = make_any_tuple(atom("REPLY"),
util::duration{rel_time},
to,
id,
std::move(data));
auto dsh = delayed_send_helper();
dsh->enqueue({self, dsh}, std::move(tup));
}
else {
this->delayed_send(to, rel_time, std::move(data));
}
CPPA_REQUIRE(hdr.id.valid() && hdr.id.is_response());
auto tup = make_any_tuple(atom("SEND"),
util::duration{rel_time},
std::move(hdr),
std::move(data));
delayed_send_helper()->enqueue(nullptr, std::move(tup));
}
/**
......
This diff is collapsed.
......@@ -82,6 +82,7 @@ class duration {
"only seconds, milliseconds or microseconds allowed");
}
// convert minutes to seconds
template<class Rep>
constexpr duration(std::chrono::duration<Rep, std::ratio<60, 1> > d)
: unit(time_unit::seconds), count(d.count() * 60) { }
......
......@@ -8,7 +8,7 @@ Typed actors use \lstinline^typed_actor_ptr<...>^ instead of \lstinline^actor_pt
For example, an actor responding to two integers with a dobule would use the type \lstinline^typed_actor_ptr<replies_to<int, int>::with<double>>^.
All functions for message passing, linking and monitoring are overloaded to accept both types of actors.
As of version 0.8, strongly typed actors cannot be published (this is a planned feature for future releases).
As of version 0.8, strongly typed actors cannot be published and do not support message priorities (those are planned feature for future releases).
\subsection{Spawning Typed Actors}
\label{sec:strong:spawn}
......
......@@ -158,10 +158,10 @@ void local_actor::reply_message(any_tuple&& what) {
}
}
void local_actor::forward_message(const actor_ptr& new_receiver) {
if (new_receiver == nullptr) return;
void local_actor::forward_message(const actor_ptr& dest, message_priority p) {
if (dest == nullptr) return;
auto& id = m_current_node->mid;
new_receiver->enqueue({last_sender(), new_receiver, id}, m_current_node->msg);
dest->enqueue({last_sender(), dest, id, p}, m_current_node->msg);
// treat this message as asynchronous message from now on
id = message_id{};
}
......
......@@ -66,17 +66,9 @@ class delayed_msg {
public:
delayed_msg(const channel_ptr& arg0,
const actor_ptr& arg1,
message_id,
any_tuple&& arg3)
: ptr_a(arg0), from(arg1), msg(move(arg3)) { }
delayed_msg(const actor_ptr& arg0,
const actor_ptr& arg1,
message_id arg2,
any_tuple&& arg3)
: ptr_b(arg0), from(arg1), id(arg2), msg(move(arg3)) { }
delayed_msg(message_header&& arg1,
any_tuple&& arg2)
: hdr(move(arg1)), msg(move(arg2)) { }
delayed_msg(delayed_msg&&) = default;
delayed_msg(const delayed_msg&) = default;
......@@ -84,18 +76,13 @@ class delayed_msg {
delayed_msg& operator=(const delayed_msg&) = default;
inline void eval() {
CPPA_REQUIRE(ptr_a || ptr_b);
if (ptr_a) ptr_a->enqueue(from, move(msg));
else ptr_b->enqueue({from, id}, move(msg));
hdr.deliver(std::move(msg));
}
private:
channel_ptr ptr_a;
actor_ptr ptr_b;
actor_ptr from;
message_id id;
any_tuple msg;
message_header hdr;
any_tuple msg;
};
......@@ -140,16 +127,14 @@ class scheduler_helper {
};
template<class Map, class T>
template<class Map>
inline void insert_dmsg(Map& storage,
const util::duration& d,
const T& to,
const actor_ptr& sender,
any_tuple&& tup,
message_id id = message_id{}) {
const util::duration& d,
message_header&& hdr,
any_tuple&& tup ) {
auto tout = hrc::now();
tout += d;
delayed_msg dmsg{to, sender, id, move(tup)};
delayed_msg dmsg{move(hdr), move(tup)};
storage.insert(std::make_pair(std::move(tout), std::move(dmsg)));
}
......@@ -163,15 +148,9 @@ void scheduler_helper::timer_loop(scheduler_helper::ptr_type m_self) {
// message handling rules
auto mfun = (
on(atom("SEND"), arg_match) >> [&](const util::duration& d,
const channel_ptr& ptr,
message_header& hdr,
any_tuple& tup) {
insert_dmsg(messages, d, ptr, msg_ptr->sender, move(tup));
},
on(atom("REPLY"), arg_match) >> [&](const util::duration& d,
const actor_ptr& ptr,
message_id id,
any_tuple& tup) {
insert_dmsg(messages, d, ptr, msg_ptr->sender, move(tup), id);
insert_dmsg(messages, d, move(hdr), move(tup));
},
on(atom("DIE")) >> [&] {
done = true;
......
......@@ -34,10 +34,10 @@
namespace cppa {
message_future sync_send_tuple(actor_ptr whom, any_tuple what) {
if (!whom) throw std::invalid_argument("whom == nullptr");
message_future sync_send_tuple(actor_destination dest, any_tuple what) {
if (!dest.receiver) throw std::invalid_argument("whom == nullptr");
auto req = self->new_request_id();
message_header hdr{self, std::move(whom), req};
message_header hdr{self, std::move(dest.receiver), req, dest.priority};
if (self->chaining_enabled()) {
if (hdr.receiver->chained_enqueue(hdr, std::move(what))) {
self->chained_actor(hdr.receiver.downcast<actor>());
......@@ -47,27 +47,30 @@ message_future sync_send_tuple(actor_ptr whom, any_tuple what) {
return req.response_id();
}
void delayed_send_tuple(const channel_ptr& to,
const util::duration& rel_time,
void delayed_send_tuple(channel_destination dest,
const util::duration& rtime,
any_tuple data) {
if (to) get_scheduler()->delayed_send(to, rel_time, std::move(data));
if (dest.receiver) {
message_header hdr{self, std::move(dest.receiver), dest.priority};
get_scheduler()->delayed_send(std::move(hdr), rtime, std::move(data));
}
}
void delayed_reply_tuple(const util::duration& rel_time,
actor_ptr whom,
message_id mid,
any_tuple data) {
if (whom) get_scheduler()->delayed_reply(whom,
rel_time,
mid,
std::move(data));
message_future timed_sync_send_tuple(actor_destination dest,
const util::duration& rtime,
any_tuple what) {
auto mf = sync_send_tuple(std::move(dest), std::move(what));
message_header hdr{self, self, mf.id()};
auto tmp = make_any_tuple(atom("TIMEOUT"));
get_scheduler()->delayed_send(std::move(hdr), rtime, std::move(tmp));
return mf;
}
void delayed_reply_tuple(const util::duration& rel_time,
void delayed_reply_tuple(const util::duration& rtime,
message_id mid,
any_tuple data) {
delayed_reply_tuple(rel_time, self->last_sender(), mid, std::move(data));
message_header hdr{self, self->last_sender(), mid};
get_scheduler()->delayed_send(std::move(hdr), rtime, std::move(data));
}
void delayed_reply_tuple(const util::duration& rel_time, any_tuple data) {
......
......@@ -66,6 +66,7 @@ class typed_testee : public typed_actor<replies_to<my_request>::with<bool>> {
int main() {
CPPA_TEST(test_typed_spawn);
announce<my_request>(&my_request::a, &my_request::b);
auto sptr = spawn_typed_server();
sync_send(sptr, my_request{2, 2}).await(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment