Commit 89c33b08 authored by Dominik Charousset's avatar Dominik Charousset

Imrpove error renders, add deep_to_string_as_tuple

parent d10d0070
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
* - ./build/bin/broker -c localhost 4242 * * - ./build/bin/broker -c localhost 4242 *
\ ******************************************************************************/ \ ******************************************************************************/
// This file is partially included in the manual, do not modify
// without updating the references in the *.tex files!
// Manual references: lines 46-50 (Actors.tex)
#include "caf/config.hpp" #include "caf/config.hpp"
#ifdef WIN32 #ifdef WIN32
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* using composable states. * * using composable states. *
\******************************************************************************/ \******************************************************************************/
// This example is partially included in the manual, do not modify // This file is partially included in the manual, do not modify
// without updating the references in the *.tex files! // without updating the references in the *.tex files!
// Manual references: lines 18-50 (Actor.tex) // Manual references: lines 18-50 (Actor.tex)
...@@ -23,8 +23,6 @@ using multiply_atom = atom_constant<atom("multiply")>; ...@@ -23,8 +23,6 @@ using multiply_atom = atom_constant<atom("multiply")>;
using adder = typed_actor<replies_to<add_atom, int, int>::with<int>>; using adder = typed_actor<replies_to<add_atom, int, int>::with<int>>;
using multiplier = typed_actor<replies_to<multiply_atom, int, int>::with<int>>; using multiplier = typed_actor<replies_to<multiply_atom, int, int>::with<int>>;
using calculator = adder::extend_with<multiplier>;
class adder_bhvr : public composable_behavior<adder> { class adder_bhvr : public composable_behavior<adder> {
public: public:
result<int> operator()(add_atom, int x, int y) override { result<int> operator()(add_atom, int x, int y) override {
...@@ -39,7 +37,7 @@ public: ...@@ -39,7 +37,7 @@ public:
} }
}; };
// calculator_bhvr can be inherited or composed further // calculator_bhvr can be inherited from or composed further
using calculator_bhvr = composed_behavior<adder_bhvr, multiplier_bhvr>; using calculator_bhvr = composed_behavior<adder_bhvr, multiplier_bhvr>;
} // namespace <anonymous> } // namespace <anonymous>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* This example is a simple dictionary implemented * using composable states. * * This example is a simple dictionary implemented * using composable states. *
\******************************************************************************/ \******************************************************************************/
// This example is partially included in the manual, do not modify // This file is partially included in the manual, do not modify
// without updating the references in the *.tex files! // without updating the references in the *.tex files!
// Manual references: lines 22-44 (Actor.tex) // Manual references: lines 22-44 (Actor.tex)
......
...@@ -32,7 +32,7 @@ void serialize(T& in_or_out, foo& x, const unsigned int) { ...@@ -32,7 +32,7 @@ void serialize(T& in_or_out, foo& x, const unsigned int) {
// also, CAF gives us `deep_to_string` for implementing `to_string` easily // also, CAF gives us `deep_to_string` for implementing `to_string` easily
std::string to_string(const foo& x) { std::string to_string(const foo& x) {
// `to_string(foo{{1, 2, 3}, 4})` prints: "foo([1, 2, 3], 4)" // `to_string(foo{{1, 2, 3}, 4})` prints: "foo([1, 2, 3], 4)"
return "foo" + deep_to_string(std::forward_as_tuple(x.a, x.b)); return "foo" + deep_to_string_as_tuple(x.a, x.b);
} }
// a pair of two ints // a pair of two ints
...@@ -56,7 +56,7 @@ void serialize(T& in_or_out, foo2& x, const unsigned int) { ...@@ -56,7 +56,7 @@ void serialize(T& in_or_out, foo2& x, const unsigned int) {
// `deep_to_string` also traverses nested containers // `deep_to_string` also traverses nested containers
std::string to_string(const foo2& x) { std::string to_string(const foo2& x) {
return "foo" + deep_to_string(std::forward_as_tuple(x.a, x.b)); return "foo" + deep_to_string_as_tuple(x.a, x.b);
} }
// receives our custom message types // receives our custom message types
......
...@@ -45,7 +45,7 @@ public: ...@@ -45,7 +45,7 @@ public:
} }
friend std::string to_string(const foo& x) { friend std::string to_string(const foo& x) {
return "foo" + deep_to_string(std::forward_as_tuple(x.a_, x.b_)); return "foo" + deep_to_string_as_tuple(x.a_, x.b_);
} }
private: private:
......
...@@ -46,7 +46,7 @@ private: ...@@ -46,7 +46,7 @@ private:
// to_string is straightforward ... // to_string is straightforward ...
std::string to_string(const foo& x) { std::string to_string(const foo& x) {
return "foo" + deep_to_string(std::forward_as_tuple(x.a(), x.b())); return "foo" + deep_to_string_as_tuple(x.a(), x.b());
} }
// ... but we need to split serialization into a saving ... // ... but we need to split serialization into a saving ...
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* for both the blocking and the event-based API. * * for both the blocking and the event-based API. *
\******************************************************************************/ \******************************************************************************/
// This example is partially included in the manual, do not modify // This file is partially included in the manual, do not modify
// without updating the references in the *.tex files! // without updating the references in the *.tex files!
// Manual references: lines 17-21, 31-65, 67-101, and 134-139 (Actor.tex) // Manual references: lines 17-21, 31-65, 67-101, and 134-139 (Actor.tex)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* for both the blocking and the event-based API. * * for both the blocking and the event-based API. *
\******************************************************************************/ \******************************************************************************/
// This example is partially included in the manual, do not modify // This file is partially included in the manual, do not modify
// without updating the references in the *.tex files! // without updating the references in the *.tex files!
// Manual references: lines 18-44, and 50-51 (Actor.tex) // Manual references: lines 18-44, and 50-51 (Actor.tex)
......
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
#include <algorithm> #include <algorithm>
#include "caf/all.hpp" #include "caf/all.hpp"
// This file is partially included in the manual, do not modify
// without updating the references in the *.tex files!
// Manual references: lines 56-75 (MessagePassing.tex)
using std::cout; using std::cout;
using std::endl; using std::endl;
using std::pair; using std::pair;
......
#include <iostream> #include <iostream>
#include "caf/all.hpp" #include "caf/all.hpp"
// This file is partially included in the manual, do not modify
// without updating the references in the *.tex files!
// Manual references: lines 15-42 (MessagePassing.tex)
using std::endl; using std::endl;
using namespace caf; using namespace caf;
...@@ -12,13 +16,11 @@ void actor_a(event_based_actor* self, calc worker) { ...@@ -12,13 +16,11 @@ void actor_a(event_based_actor* self, calc worker) {
self->request(worker, std::chrono::seconds(10), add_atom::value, 1, 2).then( self->request(worker, std::chrono::seconds(10), add_atom::value, 1, 2).then(
[=](int result) { [=](int result) {
aout(self) << "1 + 2 = " << result << endl; aout(self) << "1 + 2 = " << result << endl;
self->send_exit(worker, exit_reason::user_shutdown);
} }
); );
} }
calc::behavior_type actor_b(calc::pointer self, calc worker) { calc::behavior_type actor_b(calc::pointer self, calc worker) {
self->link_to(worker);
return { return {
[=](add_atom add, int x, int y) { [=](add_atom add, int x, int y) {
return self->delegate(worker, add, x, y); return self->delegate(worker, add, x, y);
......
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
* A very basic, interactive divider. * * A very basic, interactive divider. *
\******************************************************************************/ \******************************************************************************/
// This example is partially included in the manual, do not modify // This file is partially included in the manual, do not modify
// without updating the references in the *.tex files! // without updating the references in the *.tex files!
// Manual references: lines 18-24, 34-47, and 62-72 (MessagePassing.tex) // Manual references: lines 19-25, 35-48, and 63-73 (MessagePassing.tex);
// lines 19-34, and 51-56 (Error.tex)
#include <iostream> #include <iostream>
...@@ -47,8 +48,8 @@ divider::behavior_type divider_impl() { ...@@ -47,8 +48,8 @@ divider::behavior_type divider_impl() {
} }
int main() { int main() {
auto renderer = [](uint8_t x) { auto renderer = [](uint8_t x, atom_value, const message&) {
return to_string(static_cast<math_error>(x)); return "math_error" + deep_to_string_as_tuple(static_cast<math_error>(x));
}; };
actor_system_config cfg; actor_system_config cfg;
cfg.add_error_category(atom("math"), renderer); cfg.add_error_category(atom("math"), renderer);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Illustrates semantics of request().{then|await|receive}. * * Illustrates semantics of request().{then|await|receive}. *
\******************************************************************************/ \******************************************************************************/
// This example is partially included in the manual, do not modify // This file is partially included in the manual, do not modify
// without updating the references in the *.tex files! // without updating the references in the *.tex files!
// Manual references: lines 20-37, 39-51, 53-58, 62-64 (MessagePassing.tex) // Manual references: lines 20-37, 39-51, 53-58, 62-64 (MessagePassing.tex)
......
...@@ -54,7 +54,7 @@ public: ...@@ -54,7 +54,7 @@ public:
using portable_names = std::unordered_map<std::type_index, std::string>; using portable_names = std::unordered_map<std::type_index, std::string>;
using error_renderer = std::function<std::string (uint8_t)>; using error_renderer = std::function<std::string (uint8_t, atom_value, const message&)>;
using error_renderers = std::unordered_map<atom_value, error_renderer>; using error_renderers = std::unordered_map<atom_value, error_renderer>;
...@@ -214,6 +214,10 @@ public: ...@@ -214,6 +214,10 @@ public:
proxy_registry* network_proxies; proxy_registry* network_proxies;
private: private:
static std::string render_sec(uint8_t, atom_value, const message&);
static std::string render_exit_reason(uint8_t, atom_value, const message&);
value_factories_by_name value_factories_by_name_; value_factories_by_name value_factories_by_name_;
value_factories_by_rtti value_factories_by_rtti_; value_factories_by_rtti value_factories_by_rtti_;
portable_names type_names_by_rtti_; portable_names type_names_by_rtti_;
......
...@@ -172,6 +172,13 @@ private: ...@@ -172,6 +172,13 @@ private:
/// provide a `to_string` is mapped to `<unprintable>`. /// provide a `to_string` is mapped to `<unprintable>`.
constexpr deep_to_string_t deep_to_string = deep_to_string_t{}; constexpr deep_to_string_t deep_to_string = deep_to_string_t{};
/// Convenience function returning
/// `deep_to_string(std::forward_as_tuple(xs...))`.
template <class... Ts>
std::string deep_to_string_as_tuple(Ts&&... xs) {
return deep_to_string(std::forward_as_tuple(std::forward<Ts>(xs)...));
}
} // namespace caf } // namespace caf
#endif // CAF_DETAIL_DEEP_TO_STRING_HPP #endif // CAF_DETAIL_DEEP_TO_STRING_HPP
...@@ -17,6 +17,10 @@ ...@@ -17,6 +17,10 @@
* http://www.boost.org/LICENSE_1_0.txt. * * http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/ ******************************************************************************/
// This file is partially included in the manual, do not modify
// without updating the references in the *.tex files!
// Manual references: lines 31-51 (Error.tex)
#ifndef CAF_EXIT_REASON_HPP #ifndef CAF_EXIT_REASON_HPP
#define CAF_EXIT_REASON_HPP #define CAF_EXIT_REASON_HPP
...@@ -24,38 +28,26 @@ ...@@ -24,38 +28,26 @@
namespace caf { namespace caf {
/// This error category represents fail conditions for actors.
enum class exit_reason : uint8_t { enum class exit_reason : uint8_t {
/// Indicates that an actor finished execution without error. /// Indicates that an actor finished execution without error.
normal = 0x00, normal = 0,
/// Indicates that an actor died because of an unhandled exception.
/// Indicates that an actor finished execution because of an unhandled exception. unhandled_exception,
unhandled_exception = 0x02,
/// Indicates that the actor received an unexpected synchronous reply message.
unhandled_request_error = 0x04,
/// Indicates that the exit reason for this actor is unknown, i.e., /// Indicates that the exit reason for this actor is unknown, i.e.,
/// the actor has been terminated and no longer exists. /// the actor has been terminated and no longer exists.
unknown = 0x06, unknown,
/// Indicates that an actor pool unexpectedly ran out of workers. /// Indicates that an actor pool unexpectedly ran out of workers.
out_of_workers = 0x07, out_of_workers,
/// Indicates that an actor was forced to shutdown by a user-generated event.
/// Indicates that the actor was forced to shutdown by a user-generated event. user_shutdown,
user_shutdown = 0x10, /// Indicates that an actor was killed unconditionally.
kill,
/// Indicates that the actor was killed unconditionally.
kill = 0x11,
/// Indicates that an actor finishied execution because a connection /// Indicates that an actor finishied execution because a connection
/// to a remote link was closed unexpectedly. /// to a remote link was closed unexpectedly.
remote_link_unreachable = 0x21, remote_link_unreachable,
/// Indicates that an actor was killed because it became unreachable.
/// Indicates that the actor was killed because it became unreachable. unreachable
unreachable = 0x40,
/// Indicates that the actor was killed after receiving an error message.
unhandled_error = 0x41
}; };
/// Returns a string representation of given exit reason. /// Returns a string representation of given exit reason.
...@@ -64,9 +56,6 @@ const char* to_string(exit_reason x); ...@@ -64,9 +56,6 @@ const char* to_string(exit_reason x);
/// @relates exit_reason /// @relates exit_reason
error make_error(exit_reason); error make_error(exit_reason);
/// @relates exit_reason
error make_error(exit_reason, message context);
} // namespace caf } // namespace caf
#endif // CAF_EXIT_REASON_HPP #endif // CAF_EXIT_REASON_HPP
...@@ -55,7 +55,7 @@ void serialize(Processor& proc, index_mapping& x, const unsigned int) { ...@@ -55,7 +55,7 @@ void serialize(Processor& proc, index_mapping& x, const unsigned int) {
} }
inline std::string to_string(const index_mapping& x) { inline std::string to_string(const index_mapping& x) {
return "idx" + deep_to_string(std::forward_as_tuple(x.value)); return "idx" + deep_to_string_as_tuple(x.value);
} }
} // namespace caf } // namespace caf
......
...@@ -17,6 +17,10 @@ ...@@ -17,6 +17,10 @@
* http://www.boost.org/LICENSE_1_0.txt. * * http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/ ******************************************************************************/
// This file is partially included in the manual, do not modify
// without updating the references in the *.tex files!
// Manual references: lines 31-70 (Error.tex)
#ifndef CAF_SEC_HPP #ifndef CAF_SEC_HPP
#define CAF_SEC_HPP #define CAF_SEC_HPP
...@@ -27,10 +31,8 @@ namespace caf { ...@@ -27,10 +31,8 @@ namespace caf {
/// SEC stands for "System Error Code". This enum contains /// SEC stands for "System Error Code". This enum contains
/// error codes used internally by CAF. /// error codes used internally by CAF.
enum class sec : uint8_t { enum class sec : uint8_t {
/// Indicates that a dynamically typed actor dropped an unexpected message. /// Indicates that an actor dropped an unexpected message.
unexpected_message = 1, unexpected_message = 1,
/// Indicates that a call to `invoke_mutable` failed in a composable state.
invalid_invoke_mutable,
/// Indicates that a response message did not match the provided handler. /// Indicates that a response message did not match the provided handler.
unexpected_response, unexpected_response,
/// Indicates that the receiver of a request is no longer alive. /// Indicates that the receiver of a request is no longer alive.
......
...@@ -65,7 +65,7 @@ public: ...@@ -65,7 +65,7 @@ public:
using portable_names = std::unordered_map<std::type_index, std::string>; using portable_names = std::unordered_map<std::type_index, std::string>;
using error_renderer = std::function<std::string (uint8_t)>; using error_renderer = std::function<std::string (uint8_t, atom_value, const message&)>;
using error_renderers = std::unordered_map<atom_value, error_renderer>; using error_renderers = std::unordered_map<atom_value, error_renderer>;
......
...@@ -176,16 +176,7 @@ const uniform_type_info_map& actor_system::types() const { ...@@ -176,16 +176,7 @@ const uniform_type_info_map& actor_system::types() const {
std::string actor_system::render(const error& x) const { std::string actor_system::render(const error& x) const {
auto f = types().renderer(x.category()); auto f = types().renderer(x.category());
std::string result = "error("; return f ? f(x.code(), x.category(), x.context()) : to_string(x);
result += to_string(x.category());
result += ", ";
result += f ? f(x.code()) : std::to_string(static_cast<int>(x.code()));
if (! x.context().empty()) {
result += ", ";
result += to_string(x.context());
}
result += ")";
return result;
} }
group_manager& actor_system::groups() { group_manager& actor_system::groups() {
......
...@@ -244,9 +244,8 @@ actor_system_config::actor_system_config() ...@@ -244,9 +244,8 @@ actor_system_config::actor_system_config()
.add(opencl_device_ids, "device-ids", .add(opencl_device_ids, "device-ids",
"restricts which OpenCL devices are accessed by CAF"); "restricts which OpenCL devices are accessed by CAF");
// add renderers for default error categories // add renderers for default error categories
error_renderers_.emplace(atom("system"), [](uint8_t x) -> std::string { error_renderers_.emplace(atom("system"), render_sec);
return to_string(static_cast<sec>(x)); error_renderers_.emplace(atom("exit"), render_exit_reason);
});
} }
actor_system_config::actor_system_config(int argc, char** argv) actor_system_config::actor_system_config(int argc, char** argv)
...@@ -360,4 +359,14 @@ actor_system_config::set(const char* config_name, config_value config_value) { ...@@ -360,4 +359,14 @@ actor_system_config::set(const char* config_name, config_value config_value) {
return *this; return *this;
} }
std::string actor_system_config::render_sec(uint8_t x, atom_value,
const message&) {
return "system_error" + deep_to_string_as_tuple(static_cast<sec>(x));
}
std::string actor_system_config::render_exit_reason(uint8_t x, atom_value,
const message&) {
return "exit_reason" + deep_to_string_as_tuple(static_cast<exit_reason>(x));
}
} // namespace caf } // namespace caf
...@@ -21,29 +21,28 @@ ...@@ -21,29 +21,28 @@
namespace caf { namespace caf {
namespace {
const char* exit_reason_strings[] = {
"normal",
"unhandled_exception",
"unhandled_request_error",
"unknown",
"out_of_workers",
"user_shutdown",
"kill",
"remote_link_unreachable",
"unreachable"
};
} // namespace <anonymous>
const char* to_string(exit_reason x) { const char* to_string(exit_reason x) {
switch (x) { auto index = static_cast<size_t>(x);
case exit_reason::normal: if (index > static_cast<size_t>(exit_reason::unreachable))
return "normal"; return "<unknown>";
case exit_reason::unhandled_exception: return exit_reason_strings[index];
return "unhandled_exception";
case exit_reason::unhandled_request_error:
return "unhandled_request_error";
case exit_reason::unknown:
return "unknown";
case exit_reason::out_of_workers:
return "out_of_workers";
case exit_reason::user_shutdown:
return "user_shutdown";
case exit_reason::kill:
return "kill";
case exit_reason::remote_link_unreachable:
return "remote_link_unreachable";
case exit_reason::unhandled_error:
return "unhandled_error";
default:
return "-invalid-";
}
} }
error make_error(exit_reason x) { error make_error(exit_reason x) {
......
...@@ -261,12 +261,6 @@ behavior high_priority_testee(event_based_actor* self) { ...@@ -261,12 +261,6 @@ behavior high_priority_testee(event_based_actor* self) {
}; };
} }
struct high_priority_testee_class : event_based_actor {
behavior make_behavior() override {
return high_priority_testee(this);
}
};
behavior master(event_based_actor* self) { behavior master(event_based_actor* self) {
return ( return (
[=](ok_atom) { [=](ok_atom) {
...@@ -335,6 +329,10 @@ struct fixture { ...@@ -335,6 +329,10 @@ struct fixture {
CAF_TEST_FIXTURE_SCOPE(atom_tests, fixture) CAF_TEST_FIXTURE_SCOPE(atom_tests, fixture)
CAF_TEST(priorities) {
system.spawn<priority_aware>(high_priority_testee);
}
CAF_TEST(count_mailbox) { CAF_TEST(count_mailbox) {
system.spawn<counting_actor>(); system.spawn<counting_actor>();
} }
......
...@@ -79,7 +79,7 @@ inline std::string to_string(const new_data_msg& x) { ...@@ -79,7 +79,7 @@ inline std::string to_string(const new_data_msg& x) {
os << std::setfill('0') << std::hex << std::right; os << std::setfill('0') << std::hex << std::right;
for (auto c : x.buf) for (auto c : x.buf)
os << std::setw(2) << static_cast<int>(c); os << std::setw(2) << static_cast<int>(c);
return "new_data" + deep_to_string(std::forward_as_tuple(x.handle, os.str())); return "new_data" + deep_to_string_as_tuple(x.handle, os.str());
} }
/// @relates new_data_msg /// @relates new_data_msg
...@@ -112,8 +112,7 @@ struct data_transferred_msg { ...@@ -112,8 +112,7 @@ struct data_transferred_msg {
/// @relates data_transferred_msg /// @relates data_transferred_msg
inline std::string to_string(const data_transferred_msg& x) { inline std::string to_string(const data_transferred_msg& x) {
return "data_transferred_msg" return "data_transferred_msg"
+ deep_to_string(std::forward_as_tuple(x.handle, x.written, + deep_to_string_as_tuple(x.handle, x.written, x.remaining);
x.remaining));
} }
/// @relates data_transferred_msg /// @relates data_transferred_msg
......
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