Commit e56200ac authored by Dominik Charousset's avatar Dominik Charousset

divide sync errors in timeouts and unexpected

this patch adds `(on_)handle_sync_timeout` to `local_actor`
parent c2f9b167
......@@ -58,12 +58,16 @@ 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
......
......@@ -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
......
......@@ -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
......
#include "test.hpp"
#include "cppa/cppa.hpp"
using namespace std;
using namespace cppa;
using namespace cppa::placeholders;
......@@ -171,11 +172,13 @@ 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());
......@@ -183,7 +186,6 @@ int main() {
quit_actor(c, exit_reason::user_defined);
await_all_others_done();
CPPA_CHECKPOINT();
await_all_others_done();
CPPA_CHECKPOINT();
shutdown();
......
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