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> { ...@@ -314,7 +314,7 @@ class local_actor : public extend<actor>::with<memory_cached> {
void reply_message(any_tuple&& what); 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(); inline const actor_ptr& chained_actor();
......
...@@ -108,35 +108,26 @@ class scheduler { ...@@ -108,35 +108,26 @@ class scheduler {
virtual attachable* register_hidden_context(); virtual attachable* register_hidden_context();
template<typename Duration, typename... Data> template<typename Duration, typename... Data>
void delayed_send(const channel_ptr& to, void delayed_send(message_header hdr,
const Duration& rel_time, const Duration& rel_time,
any_tuple data ) { any_tuple data ) {
auto tup = make_any_tuple(atom("SEND"), auto tup = make_any_tuple(atom("SEND"),
util::duration{rel_time}, util::duration{rel_time},
to, std::move(hdr),
std::move(data)); std::move(data));
auto dsh = delayed_send_helper(); delayed_send_helper()->enqueue(nullptr, std::move(tup));
dsh->enqueue({self, dsh}, std::move(tup));
} }
template<typename Duration, typename... Data> template<typename Duration, typename... Data>
void delayed_reply(const actor_ptr& to, void delayed_reply(message_header hdr,
const Duration& rel_time, const Duration& rel_time,
message_id id,
any_tuple data ) { any_tuple data ) {
CPPA_REQUIRE(!id.valid() || id.is_response()); CPPA_REQUIRE(hdr.id.valid() && hdr.id.is_response());
if (id.valid()) { auto tup = make_any_tuple(atom("SEND"),
auto tup = make_any_tuple(atom("REPLY"),
util::duration{rel_time}, util::duration{rel_time},
to, std::move(hdr),
id,
std::move(data)); std::move(data));
auto dsh = delayed_send_helper(); delayed_send_helper()->enqueue(nullptr, std::move(tup));
dsh->enqueue({self, dsh}, std::move(tup));
}
else {
this->delayed_send(to, rel_time, std::move(data));
}
} }
/** /**
......
This diff is collapsed.
...@@ -82,6 +82,7 @@ class duration { ...@@ -82,6 +82,7 @@ class duration {
"only seconds, milliseconds or microseconds allowed"); "only seconds, milliseconds or microseconds allowed");
} }
// convert minutes to seconds
template<class Rep> template<class Rep>
constexpr duration(std::chrono::duration<Rep, std::ratio<60, 1> > d) constexpr duration(std::chrono::duration<Rep, std::ratio<60, 1> > d)
: unit(time_unit::seconds), count(d.count() * 60) { } : unit(time_unit::seconds), count(d.count() * 60) { }
......
...@@ -8,7 +8,7 @@ Typed actors use \lstinline^typed_actor_ptr<...>^ instead of \lstinline^actor_pt ...@@ -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>>^. 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. 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} \subsection{Spawning Typed Actors}
\label{sec:strong:spawn} \label{sec:strong:spawn}
......
...@@ -158,10 +158,10 @@ void local_actor::reply_message(any_tuple&& what) { ...@@ -158,10 +158,10 @@ void local_actor::reply_message(any_tuple&& what) {
} }
} }
void local_actor::forward_message(const actor_ptr& new_receiver) { void local_actor::forward_message(const actor_ptr& dest, message_priority p) {
if (new_receiver == nullptr) return; if (dest == nullptr) return;
auto& id = m_current_node->mid; 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 // treat this message as asynchronous message from now on
id = message_id{}; id = message_id{};
} }
......
...@@ -66,17 +66,9 @@ class delayed_msg { ...@@ -66,17 +66,9 @@ class delayed_msg {
public: public:
delayed_msg(const channel_ptr& arg0, delayed_msg(message_header&& arg1,
const actor_ptr& arg1, any_tuple&& arg2)
message_id, : hdr(move(arg1)), msg(move(arg2)) { }
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(delayed_msg&&) = default; delayed_msg(delayed_msg&&) = default;
delayed_msg(const delayed_msg&) = default; delayed_msg(const delayed_msg&) = default;
...@@ -84,17 +76,12 @@ class delayed_msg { ...@@ -84,17 +76,12 @@ class delayed_msg {
delayed_msg& operator=(const delayed_msg&) = default; delayed_msg& operator=(const delayed_msg&) = default;
inline void eval() { inline void eval() {
CPPA_REQUIRE(ptr_a || ptr_b); hdr.deliver(std::move(msg));
if (ptr_a) ptr_a->enqueue(from, move(msg));
else ptr_b->enqueue({from, id}, move(msg));
} }
private: private:
channel_ptr ptr_a; message_header hdr;
actor_ptr ptr_b;
actor_ptr from;
message_id id;
any_tuple msg; any_tuple msg;
}; };
...@@ -140,16 +127,14 @@ class scheduler_helper { ...@@ -140,16 +127,14 @@ class scheduler_helper {
}; };
template<class Map, class T> template<class Map>
inline void insert_dmsg(Map& storage, inline void insert_dmsg(Map& storage,
const util::duration& d, const util::duration& d,
const T& to, message_header&& hdr,
const actor_ptr& sender, any_tuple&& tup ) {
any_tuple&& tup,
message_id id = message_id{}) {
auto tout = hrc::now(); auto tout = hrc::now();
tout += d; 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))); 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) { ...@@ -163,15 +148,9 @@ void scheduler_helper::timer_loop(scheduler_helper::ptr_type m_self) {
// message handling rules // message handling rules
auto mfun = ( auto mfun = (
on(atom("SEND"), arg_match) >> [&](const util::duration& d, on(atom("SEND"), arg_match) >> [&](const util::duration& d,
const channel_ptr& ptr, message_header& hdr,
any_tuple& tup) { any_tuple& tup) {
insert_dmsg(messages, d, ptr, msg_ptr->sender, move(tup)); insert_dmsg(messages, d, move(hdr), 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);
}, },
on(atom("DIE")) >> [&] { on(atom("DIE")) >> [&] {
done = true; done = true;
......
...@@ -34,10 +34,10 @@ ...@@ -34,10 +34,10 @@
namespace cppa { namespace cppa {
message_future sync_send_tuple(actor_ptr whom, any_tuple what) { message_future sync_send_tuple(actor_destination dest, any_tuple what) {
if (!whom) throw std::invalid_argument("whom == nullptr"); if (!dest.receiver) throw std::invalid_argument("whom == nullptr");
auto req = self->new_request_id(); 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 (self->chaining_enabled()) {
if (hdr.receiver->chained_enqueue(hdr, std::move(what))) { if (hdr.receiver->chained_enqueue(hdr, std::move(what))) {
self->chained_actor(hdr.receiver.downcast<actor>()); self->chained_actor(hdr.receiver.downcast<actor>());
...@@ -47,27 +47,30 @@ message_future sync_send_tuple(actor_ptr whom, any_tuple what) { ...@@ -47,27 +47,30 @@ message_future sync_send_tuple(actor_ptr whom, any_tuple what) {
return req.response_id(); return req.response_id();
} }
void delayed_send_tuple(const channel_ptr& to, void delayed_send_tuple(channel_destination dest,
const util::duration& rel_time, const util::duration& rtime,
any_tuple data) { 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, message_future timed_sync_send_tuple(actor_destination dest,
actor_ptr whom, const util::duration& rtime,
message_id mid, any_tuple what) {
any_tuple data) { auto mf = sync_send_tuple(std::move(dest), std::move(what));
if (whom) get_scheduler()->delayed_reply(whom, message_header hdr{self, self, mf.id()};
rel_time, auto tmp = make_any_tuple(atom("TIMEOUT"));
mid, get_scheduler()->delayed_send(std::move(hdr), rtime, std::move(tmp));
std::move(data)); return mf;
} }
void delayed_reply_tuple(const util::duration& rtime,
void delayed_reply_tuple(const util::duration& rel_time,
message_id mid, message_id mid,
any_tuple data) { 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) { 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>> { ...@@ -66,6 +66,7 @@ class typed_testee : public typed_actor<replies_to<my_request>::with<bool>> {
int main() { int main() {
CPPA_TEST(test_typed_spawn); CPPA_TEST(test_typed_spawn);
announce<my_request>(&my_request::a, &my_request::b); announce<my_request>(&my_request::a, &my_request::b);
auto sptr = spawn_typed_server(); auto sptr = spawn_typed_server();
sync_send(sptr, my_request{2, 2}).await( 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