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 @@
* - ./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"
#ifdef WIN32
......
......@@ -3,7 +3,7 @@
* 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!
// Manual references: lines 18-50 (Actor.tex)
......@@ -23,8 +23,6 @@ using multiply_atom = atom_constant<atom("multiply")>;
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 calculator = adder::extend_with<multiplier>;
class adder_bhvr : public composable_behavior<adder> {
public:
result<int> operator()(add_atom, int x, int y) override {
......@@ -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>;
} // namespace <anonymous>
......
......@@ -2,7 +2,7 @@
* 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!
// Manual references: lines 22-44 (Actor.tex)
......
......@@ -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
std::string to_string(const foo& x) {
// `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
......@@ -56,7 +56,7 @@ void serialize(T& in_or_out, foo2& x, const unsigned int) {
// `deep_to_string` also traverses nested containers
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
......
......@@ -45,7 +45,7 @@ public:
}
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:
......
......@@ -46,7 +46,7 @@ private:
// to_string is straightforward ...
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 ...
......
......@@ -3,7 +3,7 @@
* 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!
// Manual references: lines 17-21, 31-65, 67-101, and 134-139 (Actor.tex)
......
......@@ -3,7 +3,7 @@
* 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!
// Manual references: lines 18-44, and 50-51 (Actor.tex)
......
......@@ -7,6 +7,10 @@
#include <algorithm>
#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::endl;
using std::pair;
......
#include <iostream>
#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 namespace caf;
......@@ -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(
[=](int result) {
aout(self) << "1 + 2 = " << result << endl;
self->send_exit(worker, exit_reason::user_shutdown);
}
);
}
calc::behavior_type actor_b(calc::pointer self, calc worker) {
self->link_to(worker);
return {
[=](add_atom add, int x, int y) {
return self->delegate(worker, add, x, y);
......
......@@ -2,9 +2,10 @@
* 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!
// 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>
......@@ -47,8 +48,8 @@ divider::behavior_type divider_impl() {
}
int main() {
auto renderer = [](uint8_t x) {
return to_string(static_cast<math_error>(x));
auto renderer = [](uint8_t x, atom_value, const message&) {
return "math_error" + deep_to_string_as_tuple(static_cast<math_error>(x));
};
actor_system_config cfg;
cfg.add_error_category(atom("math"), renderer);
......
......@@ -2,7 +2,7 @@
* 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!
// Manual references: lines 20-37, 39-51, 53-58, 62-64 (MessagePassing.tex)
......
......@@ -54,7 +54,7 @@ public:
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>;
......@@ -214,6 +214,10 @@ public:
proxy_registry* network_proxies;
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_rtti value_factories_by_rtti_;
portable_names type_names_by_rtti_;
......
......@@ -172,6 +172,13 @@ private:
/// provide a `to_string` is mapped to `<unprintable>`.
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
#endif // CAF_DETAIL_DEEP_TO_STRING_HPP
......@@ -17,6 +17,10 @@
* 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
#define CAF_EXIT_REASON_HPP
......@@ -24,38 +28,26 @@
namespace caf {
/// This error category represents fail conditions for actors.
enum class exit_reason : uint8_t {
/// Indicates that an actor finished execution without error.
normal = 0x00,
/// Indicates that an actor finished execution because of an unhandled exception.
unhandled_exception = 0x02,
/// Indicates that the actor received an unexpected synchronous reply message.
unhandled_request_error = 0x04,
normal = 0,
/// Indicates that an actor died because of an unhandled exception.
unhandled_exception,
/// Indicates that the exit reason for this actor is unknown, i.e.,
/// the actor has been terminated and no longer exists.
unknown = 0x06,
unknown,
/// Indicates that an actor pool unexpectedly ran out of workers.
out_of_workers = 0x07,
/// Indicates that the actor was forced to shutdown by a user-generated event.
user_shutdown = 0x10,
/// Indicates that the actor was killed unconditionally.
kill = 0x11,
out_of_workers,
/// Indicates that an actor was forced to shutdown by a user-generated event.
user_shutdown,
/// Indicates that an actor was killed unconditionally.
kill,
/// Indicates that an actor finishied execution because a connection
/// to a remote link was closed unexpectedly.
remote_link_unreachable = 0x21,
/// Indicates that the actor was killed because it became unreachable.
unreachable = 0x40,
/// Indicates that the actor was killed after receiving an error message.
unhandled_error = 0x41
remote_link_unreachable,
/// Indicates that an actor was killed because it became unreachable.
unreachable
};
/// Returns a string representation of given exit reason.
......@@ -64,9 +56,6 @@ const char* to_string(exit_reason x);
/// @relates exit_reason
error make_error(exit_reason);
/// @relates exit_reason
error make_error(exit_reason, message context);
} // namespace caf
#endif // CAF_EXIT_REASON_HPP
......@@ -55,7 +55,7 @@ void serialize(Processor& proc, index_mapping& x, const unsigned int) {
}
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
......
......@@ -17,6 +17,10 @@
* 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
#define CAF_SEC_HPP
......@@ -27,10 +31,8 @@ namespace caf {
/// SEC stands for "System Error Code". This enum contains
/// error codes used internally by CAF.
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,
/// 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.
unexpected_response,
/// Indicates that the receiver of a request is no longer alive.
......
......@@ -65,7 +65,7 @@ public:
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>;
......
......@@ -176,16 +176,7 @@ const uniform_type_info_map& actor_system::types() const {
std::string actor_system::render(const error& x) const {
auto f = types().renderer(x.category());
std::string result = "error(";
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;
return f ? f(x.code(), x.category(), x.context()) : to_string(x);
}
group_manager& actor_system::groups() {
......
......@@ -244,9 +244,8 @@ actor_system_config::actor_system_config()
.add(opencl_device_ids, "device-ids",
"restricts which OpenCL devices are accessed by CAF");
// add renderers for default error categories
error_renderers_.emplace(atom("system"), [](uint8_t x) -> std::string {
return to_string(static_cast<sec>(x));
});
error_renderers_.emplace(atom("system"), render_sec);
error_renderers_.emplace(atom("exit"), render_exit_reason);
}
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) {
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
......@@ -21,29 +21,28 @@
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) {
switch (x) {
case exit_reason::normal:
return "normal";
case exit_reason::unhandled_exception:
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-";
}
auto index = static_cast<size_t>(x);
if (index > static_cast<size_t>(exit_reason::unreachable))
return "<unknown>";
return exit_reason_strings[index];
}
error make_error(exit_reason x) {
......
......@@ -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) {
return (
[=](ok_atom) {
......@@ -335,6 +329,10 @@ struct fixture {
CAF_TEST_FIXTURE_SCOPE(atom_tests, fixture)
CAF_TEST(priorities) {
system.spawn<priority_aware>(high_priority_testee);
}
CAF_TEST(count_mailbox) {
system.spawn<counting_actor>();
}
......
......@@ -79,7 +79,7 @@ inline std::string to_string(const new_data_msg& x) {
os << std::setfill('0') << std::hex << std::right;
for (auto c : x.buf)
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
......@@ -112,8 +112,7 @@ struct data_transferred_msg {
/// @relates data_transferred_msg
inline std::string to_string(const data_transferred_msg& x) {
return "data_transferred_msg"
+ deep_to_string(std::forward_as_tuple(x.handle, x.written,
x.remaining));
+ deep_to_string_as_tuple(x.handle, x.written, x.remaining);
}
/// @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