Permalink
Browse files

divide sync errors in timeouts and unexpected

this patch adds `(on_)handle_sync_timeout` to `local_actor`
  • Loading branch information...
1 parent c2f9b16 commit e56200ac02167a3286b13b67ad7a385a2ef47c6e @Neverlord Neverlord committed Feb 19, 2013
Showing with 64 additions and 24 deletions.
  1. +7 −3 cppa/exit_reason.hpp
  2. +45 −15 cppa/local_actor.hpp
  3. +8 −4 cppa/message_future.hpp
  4. +4 −2 unit_testing/test_sync_send.cpp
View
@@ -58,13 +58,17 @@ static constexpr std::uint32_t unhandled_exception = 0x00002;
static constexpr std::uint32_t unallowed_function_call = 0x00003;
/**
- * @brief Indicates that a synchronous message timed out
- * or the receiving actor didn't handle the message properly
- * and the killed actor did not handle sync failures manually.
+ * @brief Indicates that the actor received an unexpected
+ * synchronous reply message.
*/
static constexpr std::uint32_t unhandled_sync_failure = 0x00004;
/**
+ * @brief Indicates that a synchronous message timed out.
+ */
+static constexpr std::uint32_t unhandled_sync_timeout = 0x00005;
+
+/**
* @brief Indicates that an actor finishied execution
* because a connection to a remote link was
* closed unexpectedly.
View
@@ -355,6 +355,50 @@ class local_actor : public memory_cached_mixin<actor> {
*/
virtual void exec_behavior_stack();
+ /**
+ * @brief Creates a {@link response_handle} to allow actors to response
+ * to a request later on.
+ */
+ response_handle make_response_handle();
+
+ /**
+ * @brief Sets the handler for unexpected synchronous response messages.
+ */
+ inline void on_sync_timeout(std::function<void()> fun) {
+ m_sync_timeout_handler = std::move(fun);
+ }
+
+ /**
+ * @brief Sets the handler for @p timed_sync_send timeout messages.
+ */
+ inline void on_sync_failure(std::function<void()> fun) {
+ m_sync_failure_handler = std::move(fun);
+ }
+
+ /**
+ * @brief Calls <tt>on_sync_timeout(fun); on_sync_failure(fun);</tt>.
+ */
+ inline void on_sync_timeout_or_failure(std::function<void()> fun) {
+ on_sync_timeout(fun);
+ on_sync_failure(fun);
+ }
+
+ /**
+ * @brief Invokes the handler for synchronous timeouts.
+ */
+ inline void handle_sync_timeout() {
+ if (m_sync_timeout_handler) m_sync_timeout_handler();
+ else quit(exit_reason::unhandled_sync_timeout);
+ }
+
+ /**
+ * @brief Invokes the handler for unexpected synchronous response messages.
+ */
+ inline void handle_sync_failure() {
+ if (m_sync_failure_handler) m_sync_failure_handler();
+ else quit(exit_reason::unhandled_sync_failure);
+ }
+
// library-internal members and member functions that shall
// not appear in the documentation
@@ -442,21 +486,6 @@ class local_actor : public memory_cached_mixin<actor> {
virtual void become_waiting_for(behavior&&, message_id_t) = 0;
- /**
- * @brief Creates a {@link response_handle} to allow actors to response
- * to a request later on.
- */
- response_handle make_response_handle();
-
- inline void on_sync_failure(std::function<void()> fun) {
- m_sync_failure_handler = std::move(fun);
- }
-
- inline void handle_sync_failure() {
- if (m_sync_failure_handler) m_sync_failure_handler();
- else quit(exit_reason::unhandled_sync_failure);
- }
-
inline detail::behavior_stack& bhvr_stack() {
return m_bhvr_stack;
}
@@ -492,6 +521,7 @@ class local_actor : public memory_cached_mixin<actor> {
private:
std::function<void()> m_sync_failure_handler;
+ std::function<void()> m_sync_timeout_handler;
# endif // CPPA_DOCUMENTATION
View
@@ -95,7 +95,7 @@ class message_future {
/**
* @brief Sets @p fun as event-handler for the response message, calls
* <tt>self->handle_sync_failure()</tt> if the response message
- * is an 'EXITED', 'TIMEOUT', or 'VOID' message.
+ * is an 'EXITED' or 'VOID' message.
*/
template<typename F>
typename std::enable_if<util::is_callable<F>::value,continue_helper>::type
@@ -108,7 +108,7 @@ class message_future {
/**
* @brief Blocks until the response arrives and then executes @p @p fun,
* calls <tt>self->handle_sync_failure()</tt> if the response
- * message is an 'EXITED', 'TIMEOUT', or 'VOID' message.
+ * message is an 'EXITED' or 'VOID' message.
*/
template<typename F>
typename std::enable_if<util::is_callable<F>::value>::type await(F fun) {
@@ -142,9 +142,13 @@ class message_future {
// continuation to be invoked only in case
// `fun` was invoked
};
+ auto handle_sync_timeout = []() -> bool {
+ self->handle_sync_timeout();
+ return false;
+ };
return {
- on(atom("EXITED"), any_vals) >> handle_sync_failure,
- on(atom("TIMEOUT")) >> handle_sync_failure,
+ on<atom("EXITED"), std::uint32_t>() >> handle_sync_failure,
+ on(atom("TIMEOUT")) >> handle_sync_timeout,
on(atom("VOID")) >> handle_sync_failure,
on(any_vals, arg_match) >> fun,
others() >> handle_sync_failure
@@ -1,6 +1,7 @@
#include "test.hpp"
#include "cppa/cppa.hpp"
+using namespace std;
using namespace cppa;
using namespace cppa::placeholders;
@@ -171,19 +172,20 @@ int main() {
// check wheter continuations are invoked correctly
auto c = spawn<C>(); // replies only to 'gogo' messages
// first test: sync error must occur, continuation must not be called
- self->on_sync_failure(CPPA_CHECKPOINT_CB());
+ bool timeout_occured = false;
+ self->on_sync_timeout([&] { timeout_occured = true; });
timed_sync_send(c, std::chrono::milliseconds(500), atom("HiThere"))
.then(CPPA_ERROR_CB("C replied to 'HiThere'!"))
.continue_with(CPPA_ERROR_CB("bad continuation"));
self->exec_behavior_stack();
+ CPPA_CHECK_EQUAL(timeout_occured, true);
self->on_sync_failure(CPPA_UNEXPECTED_MSG_CB());
sync_send(c, atom("gogo")).then(CPPA_CHECKPOINT_CB())
.continue_with(CPPA_CHECKPOINT_CB());
self->exec_behavior_stack();
quit_actor(c, exit_reason::user_defined);
await_all_others_done();
CPPA_CHECKPOINT();
-
await_all_others_done();
CPPA_CHECKPOINT();
shutdown();

0 comments on commit e56200a

Please sign in to comment.