Commit a6b6130b authored by Dominik Charousset's avatar Dominik Charousset

Merge branch 'issue/1116'

Close #1116.
parents 13b5d670 c6f9177e
......@@ -54,14 +54,6 @@ is based on [Keep a Changelog](https://keepachangelog.com).
- The `to_string` output for `error` now renders the error code enum by default.
This renders the member functions `actor_system::render` and
`actor_system_config::render` obsolete.
- The configuration format of CAF has come a long way since first starting to
allow user-defined configuration via `.ini` files. Rather than sticking with
the weird hybrid that evolved over the years, we are going to get rid of the
last pieces of INI syntax and go with the much cleaner, scoped syntax. CAF is
still picking up `caf-application.ini` with this release and uses the
deprecated INI parser when given any other file name that ends in `.ini`.
However, the next version of CAF is only going to recognize the new format.
The new default file name is `caf-application.conf`.
### Changed
......@@ -148,6 +140,11 @@ is based on [Keep a Changelog](https://keepachangelog.com).
- All member functions of `scheduled_actor` for adding stream managers (such as
`make_source`) were removed in favor their free-function equivalent, e.g.,
`attach_stream_source`
- The configuration format of CAF has come a long way since first starting to
allow user-defined configuration via `.ini` files. Rather than sticking with
the weird hybrid that evolved over the years, we finally get rid of the last
pieces of INI syntax and go with the much cleaner, scoped syntax. The new
default file name for configuration files is `caf-application.conf`.
### Fixed
......
# This file shows all possible parameters with defaults. For some values, CAF
# computes a value at runtime if the configuration does not provide a value. For
# example, "scheduler.max-threads" has no hard-coded default and instead adjusts
# to the number of cores available.
# when using the default scheduler
scheduler {
# accepted alternative: "sharing"
policy="stealing"
# configures whether the scheduler generates profiling output
enable-profiling=false
# forces a fixed number of threads if set
# max-threads=... (detected at runtime)
# maximum number of messages actors can consume in one run (int64 max)
max-throughput=9223372036854775807
# measurement resolution in milliseconds (only if profiling is enabled)
profiling-resolution=100ms
# output file for profiler data (only if profiling is enabled)
profiling-output-file="/dev/null"
}
# when using "stealing" as scheduler policy
work-stealing {
# number of zero-sleep-interval polling attempts
aggressive-poll-attempts=100
# frequency of steal attempts during aggressive polling
aggressive-steal-interval=10
# number of moderately aggressive polling attempts
moderate-poll-attempts=500
# frequency of steal attempts during moderate polling
moderate-steal-interval=5
# sleep interval between poll attempts
moderate-sleep-duration=50us
# frequency of steal attempts during relaxed polling
relaxed-steal-interval=1
# sleep interval between poll attempts
relaxed-sleep-duration=10ms
}
# when loading io::middleman
middleman {
# configures whether MMs try to span a full mesh
enable-automatic-connections=false
# application identifier of this node, prevents connection to other CAF
# instances with different identifier
app-identifier=""
# maximum number of consecutive I/O reads per broker
max-consecutive-reads=50
# heartbeat message interval in ms (0 disables heartbeating)
heartbeat-interval=0ms
# configures whether the MM attaches its internal utility actors to the
# scheduler instead of dedicating individual threads (needed only for
# deterministic testing)
attach-utility-actors=false
# configures whether the MM starts a background thread for I/O activity,
# setting this to true allows fully deterministic execution in unit test and
# requires the user to trigger I/O manually
manual-multiplexing=false
# disables communication via TCP
disable-tcp=false
# enable communication via UDP
enable-udp=false
# configures how many background workers are spawned for deserialization,
# by default CAF uses 1-4 workers depending on the number of cores
# workers=... (detected at runtime)
}
# when compiling with logging enabled
logger {
# file name template for output log file files (empty string disables logging)
file-name="actor_log_[PID]_[TIMESTAMP]_[NODE].log"
# format for rendering individual log file entries
file-format="%r %c %p %a %t %C %M %F:%L %m%n"
# configures the minimum severity of messages that are written to the log file
# (quiet|error|warning|info|debug|trace)
file-verbosity="trace"
# mode for console log output generation (none|colored|uncolored)
console="none"
# format for printing individual log entries to the console
console-format="%m"
# configures the minimum severity of messages that are written to the console
# (quiet|error|warning|info|debug|trace)
console-verbosity="trace"
# excludes listed components from logging (list of strings)
component-blacklist=[]
# example, "caf.scheduler.max-threads" has no hard-coded default and instead
# adjusts to the number of cores available.
caf {
# Parameters selecting a default scheduler.
scheduler {
# Use the work stealing implementation. Accepted alternative: "sharing".
policy = "stealing"
# Maximum number of messages actors can consume in single run (int64 max).
max-throughput = 9223372036854775807
# # Maximum number of threads for the scheduler. No hardcoded default.
# max-threads = ... (detected at runtime)
}
# Prameters for the work stealing scheduler. Only takes effect if
# caf.scheduler.policy is set to "stealing".
work-stealing {
# Number of zero-sleep-interval polling attempts.
aggressive-poll-attempts = 100
# Frequency of steal attempts during aggressive polling.
aggressive-steal-interval = 10
# Number of moderately aggressive polling attempts.
moderate-poll-attempts = 500
# Frequency of steal attempts during moderate polling.
moderate-steal-interval = 5
# Sleep interval between poll attempts.
moderate-sleep-duration = 50us
# Frequency of steal attempts during relaxed polling.
relaxed-steal-interval = 1
# Sleep interval between poll attempts.
relaxed-sleep-duration = 10ms
}
# Parameters for the I/O module.
middleman {
# Configures whether MMs try to span a full mesh.
enable-automatic-connections = false
# Application identifiers of this node, prevents connection to other CAF
# instances with incompatible identifiers.
app-identifiers = ["generic-caf-app"]
# Maximum number of consecutive I/O reads per broker.
max-consecutive-reads = 50
# Heartbeat message interval in ms (0 disables heartbeating).
heartbeat-interval = 0ms
# Configures whether the MM attaches its internal utility actors to the
# scheduler instead of dedicating individual threads (needed only for
# deterministic testing).
attach-utility-actors = false
# Configures whether the MM starts a background thread for I/O activity.
# Setting this to true allows fully deterministic execution in unit test and
# requires the user to trigger I/O manually.
manual-multiplexing = false
# # Configures how many background workers are spawned for deserialization.
# # No hardcoded default.
# workers = ... (detected at runtime)
}
# Parameters for logging.
logger {
# # Note: File logging is disabled unless a 'file' section exists that
# # contains a setting for 'verbosity'.
# file {
# # File name template for output log files.
# path = "actor_log_[PID]_[TIMESTAMP]_[NODE].log"
# # Format for rendering individual log file entries.
# format = "%r %c %p %a %t %C %M %F:%L %m%n"
# # Minimum severity of messages that are written to the log. One of:
# # 'quiet', 'error', 'warning', 'info', 'debug', or 'trace'.
# verbosity = "trace"
# # A list of components to exclude in file output.
# excluded-components = []
# }
# # Note: Console output is disabled unless a 'console' section exists that
# # contains a setting for 'verbosity'.
# console {
# # Enabled colored output when writing to a TTY if set to true.
# colored = true
# # Format for printing log lines (implicit newline at the end).
# format = "[%c:%p] %d %m"
# # Minimum severity of messages that are written to the console. One of:
# # 'quiet', 'error', 'warning', 'info', 'debug', or 'trace'.
# verbosity = "trace"
# # A list of components to exclude in console output.
# excluded-components = []
# }
}
}
......@@ -84,7 +84,6 @@ add_library(libcaf_core_obj OBJECT ${CAF_CORE_HEADERS}
src/detail/get_process_id.cpp
src/detail/get_root_uuid.cpp
src/detail/glob_match.cpp
src/detail/ini_consumer.cpp
src/detail/invoke_result_visitor.cpp
src/detail/message_builder_element.cpp
src/detail/message_data.cpp
......@@ -237,14 +236,12 @@ caf_add_test_suites(caf-core-test
detail.bounds_checker
detail.config_consumer
detail.ieee_754
detail.ini_consumer
detail.limited_vector
detail.meta_object
detail.parse
detail.parser.read_bool
detail.parser.read_config
detail.parser.read_floating_point
detail.parser.read_ini
detail.parser.read_number
detail.parser.read_number_or_timespan
detail.parser.read_signed_integer
......
......@@ -99,7 +99,7 @@ public:
/// values.
virtual settings dump_content() const;
/// Sets a config by using its INI name `config_name` to `config_value`.
/// Sets a config by using its name `config_name` to `config_value`.
template <class T>
actor_system_config& set(string_view name, T&& value) {
return set_impl(name, config_value{std::forward<T>(value)});
......@@ -113,16 +113,15 @@ public:
/// Parses `args` as tuple of strings containing CLI options and tries to open
/// `config_file_cstr` as config file. The parsers tries to open
/// `caf-application.conf` or `caf-application.ini` (deprecated) if
/// `config_file_cstr` is `nullptr`.
/// `caf-application.conf` if `config_file_cstr` is `nullptr`.
error parse(string_list args, const char* config_file_cstr = nullptr);
/// Parses the CLI options `{argc, argv}` and `config` as configuration file.
error parse(int argc, char** argv, std::istream& config);
/// Parses the CLI options `{argc, argv}` and tries to open `config_file_cstr`
/// as config file. The parsers tries to open `caf-application.conf` or
/// `caf-application.ini` (deprecated) if `config_file_cstr` is `nullptr`.
/// as config file. The parsers tries to open `caf-application.conf` if
/// `config_file_cstr` is `nullptr`.
error parse(int argc, char** argv, const char* config_file_cstr = nullptr);
/// Allows other nodes to spawn actors created by `fun`
......@@ -247,7 +246,7 @@ public:
// -- parsing parameters -----------------------------------------------------
/// Configures the file path for the INI file, `caf-application.ini` per
/// Configures the file path for the config file, `caf-application.conf` per
/// default.
std::string config_file_path;
......@@ -324,17 +323,9 @@ protected:
config_option_set custom_options_;
private:
// TODO: deprecated. Remove with CAF 0.19.
static error parse_ini(std::istream& source, const config_option_set& opts,
settings& result);
actor_system_config& set_impl(string_view name, config_value value);
error extract_config_file_path(string_list& args);
/// Adjusts the content of the configuration, e.g., for ensuring backwards
/// compatibility with older options.
error adjust_content();
};
/// Returns all user-provided configuration parameters.
......
......@@ -68,33 +68,19 @@ constexpr auto relaxed_sleep_duration = timespan{10'000'000};
} // namespace caf::defaults::work_stealing
namespace caf::defaults::logger {
constexpr auto default_log_level = string_view {
#if CAF_LOG_LEVEL == CAF_LOG_LEVEL_TRACE
"trace"
#elif CAF_LOG_LEVEL == CAF_LOG_LEVEL_DEBUG
"debug"
#elif CAF_LOG_LEVEL == CAF_LOG_LEVEL_INFO
"info"
#elif CAF_LOG_LEVEL == CAF_LOG_LEVEL_WARNING
"warning"
#elif CAF_LOG_LEVEL == CAF_LOG_LEVEL_ERROR
"error"
#else
"quiet"
#endif
};
constexpr auto console = string_view{"none"};
constexpr auto console_format = string_view{"%m"};
constexpr auto console_verbosity = default_log_level;
constexpr auto file_format = string_view{"%r %c %p %a %t %C %M %F:%L %m%n"};
constexpr auto file_verbosity = default_log_level;
constexpr auto file_name
= string_view{"actor_log_[PID]_[TIMESTAMP]_[NODE].log"};
} // namespace caf::defaults::logger
namespace caf::defaults::logger::file {
constexpr auto format = string_view{"%r %c %p %a %t %C %M %F:%L %m%n"};
constexpr auto path = string_view{"actor_log_[PID]_[TIMESTAMP]_[NODE].log"};
} // namespace caf::defaults::logger::file
namespace caf::defaults::logger::console {
constexpr auto colored = true;
constexpr auto format = string_view{"[%c:%p] %d %m"};
} // namespace caf::defaults::logger::console
namespace caf::defaults::middleman {
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <string>
#include "caf/config_option_set.hpp"
#include "caf/config_value.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/dictionary.hpp"
#include "caf/settings.hpp"
namespace caf::detail {
class ini_consumer;
class ini_list_consumer;
class ini_map_consumer;
class CAF_CORE_EXPORT abstract_ini_consumer {
public:
// -- constructors, destructors, and assignment operators --------------------
explicit abstract_ini_consumer(abstract_ini_consumer* parent = nullptr);
abstract_ini_consumer(const abstract_ini_consumer&) = delete;
abstract_ini_consumer& operator=(const abstract_ini_consumer&) = delete;
virtual ~abstract_ini_consumer();
// -- properties -------------------------------------------------------------
virtual void value_impl(config_value&& x) = 0;
template <class T>
void value(T&& x) {
value_impl(config_value{std::forward<T>(x)});
}
abstract_ini_consumer* parent() {
return parent_;
}
ini_map_consumer begin_map();
ini_list_consumer begin_list();
protected:
// -- member variables -------------------------------------------------------
abstract_ini_consumer* parent_;
};
class CAF_CORE_EXPORT ini_map_consumer : public abstract_ini_consumer {
public:
// -- member types -----------------------------------------------------------
using super = abstract_ini_consumer;
using map_type = config_value::dictionary;
using iterator = map_type::iterator;
// -- constructors, destructors, and assignment operators --------------------
ini_map_consumer(abstract_ini_consumer* ptr);
ini_map_consumer(ini_map_consumer&& other);
~ini_map_consumer() override;
// -- properties -------------------------------------------------------------
void end_map();
void key(std::string name);
void value_impl(config_value&& x) override;
private:
// -- member variables -------------------------------------------------------
map_type xs_;
iterator i_;
};
class CAF_CORE_EXPORT ini_list_consumer : public abstract_ini_consumer {
public:
// -- member types -----------------------------------------------------------
using super = abstract_ini_consumer;
// -- constructors, destructors, and assignment operators --------------------
ini_list_consumer(abstract_ini_consumer* ptr);
ini_list_consumer(ini_list_consumer&& other);
// -- properties -------------------------------------------------------------
void end_list();
void value_impl(config_value&& x) override;
private:
// -- member variables -------------------------------------------------------
config_value::list xs_;
};
/// Consumes a single value from an INI parser.
class CAF_CORE_EXPORT ini_value_consumer : public abstract_ini_consumer {
public:
// -- member types -----------------------------------------------------------
using super = abstract_ini_consumer;
// -- constructors, destructors, and assignment operators --------------------
explicit ini_value_consumer(abstract_ini_consumer* parent = nullptr);
// -- properties -------------------------------------------------------------
void value_impl(config_value&& x) override;
// -- member variables -------------------------------------------------------
config_value result;
};
/// Consumes a config category.
class CAF_CORE_EXPORT ini_category_consumer : public abstract_ini_consumer {
public:
// -- member types -----------------------------------------------------------
using super = abstract_ini_consumer;
// -- constructors, destructors, and assignment operators --------------------
ini_category_consumer(ini_consumer* parent, std::string category);
ini_category_consumer(ini_category_consumer&&);
// -- properties -------------------------------------------------------------
void end_map();
void key(std::string name);
void value_impl(config_value&& x) override;
private:
// -- properties -------------------------------------------------------------
ini_consumer* dparent();
// -- member variables -------------------------------------------------------
std::string category_;
config_value::dictionary xs_;
std::string current_key;
};
/// Consumes a series of dictionaries forming a application configuration.
class CAF_CORE_EXPORT ini_consumer : public abstract_ini_consumer {
public:
// -- friends ----------------------------------------------------------------
friend class ini_category_consumer;
// -- member types -----------------------------------------------------------
using super = abstract_ini_consumer;
using config_map = dictionary<config_value::dictionary>;
// -- constructors, destructors, and assignment operators --------------------
ini_consumer(const config_option_set& options, settings& cfg);
// -- properties -------------------------------------------------------------
ini_category_consumer begin_map();
void key(std::string name);
void value_impl(config_value&& x) override;
private:
// -- member variables -------------------------------------------------------
const config_option_set& options_;
settings& cfg_;
std::string current_key_;
std::vector<error> warnings_;
};
} // namespace caf::detail
This diff is collapsed.
......@@ -340,8 +340,15 @@ private:
// Configures verbosity and output generation.
config cfg_;
// Filters events by component name.
std::vector<std::string> component_blacklist;
// Filters events by component name before enqueuing a log event. Union of
// file_filter_ and console_filter_ if both outputs are enabled.
std::vector<std::string> global_filter_;
// Filters events by component name for file output.
std::vector<std::string> file_filter_;
// Filters events by component name for console output.
std::vector<std::string> console_filter_;
// References the parent system.
actor_system& system_;
......
......@@ -320,7 +320,7 @@ actor_system::actor_system(actor_system_config& cfg)
};
sched_conf sc = stealing;
namespace sr = defaults::scheduler;
auto sr_policy = get_or(cfg, "scheduler.policy", sr::policy);
auto sr_policy = get_or(cfg, "caf.scheduler.policy", sr::policy);
if (sr_policy == "sharing")
sc = sharing;
else if (sr_policy == "testing")
......
This diff is collapsed.
......@@ -236,9 +236,7 @@ config_option_set::parse(settings& config,
}
config_option_set::option_pointer
config_option_set::cli_long_name_lookup(string_view input) const {
// We accept "caf#" prefixes for backward compatibility, but ignore them.
auto name = input.substr(input.compare(0, 4, "caf#") != 0 ? 0u : 4u);
config_option_set::cli_long_name_lookup(string_view name) const {
// Extract category and long name.
string_view category;
string_view long_name;
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/detail/ini_consumer.hpp"
#include "caf/pec.hpp"
namespace caf::detail {
// -- abstract_ini_consumer ----------------------------------------------------
abstract_ini_consumer::abstract_ini_consumer(abstract_ini_consumer* parent)
: parent_(parent) {
// nop
}
abstract_ini_consumer::~abstract_ini_consumer() {
// nop
}
ini_map_consumer abstract_ini_consumer::begin_map() {
return {this};
}
ini_list_consumer abstract_ini_consumer::begin_list() {
return {this};
}
// -- map_consumer -------------------------------------------------------------
ini_map_consumer::ini_map_consumer(abstract_ini_consumer* parent)
: super(parent), i_(xs_.end()) {
CAF_ASSERT(parent != nullptr);
}
ini_map_consumer::ini_map_consumer(ini_map_consumer&& other)
: super(other.parent()) {
}
ini_map_consumer::~ini_map_consumer() {
// nop
}
void ini_map_consumer::end_map() {
parent_->value_impl(config_value{std::move(xs_)});
}
void ini_map_consumer::key(std::string name) {
i_ = xs_.emplace(std::move(name), config_value{}).first;
}
void ini_map_consumer::value_impl(config_value&& x) {
CAF_ASSERT(i_ != xs_.end());
i_->second = std::move(x);
}
// -- ini_list_consumer --------------------------------------------------------
ini_list_consumer::ini_list_consumer(abstract_ini_consumer* parent)
: super(parent) {
CAF_ASSERT(parent != nullptr);
}
ini_list_consumer::ini_list_consumer(ini_list_consumer&& other)
: super(other.parent()), xs_(std::move(other.xs_)) {
// nop
}
void ini_list_consumer::end_list() {
parent_->value_impl(config_value{std::move(xs_)});
}
void ini_list_consumer::value_impl(config_value&& x) {
xs_.emplace_back(std::move(x));
}
// -- ini_value_consumer -------------------------------------------------------
ini_value_consumer::ini_value_consumer(abstract_ini_consumer* parent)
: super(parent) {
// nop
}
void ini_value_consumer::value_impl(config_value&& x) {
result = std::move(x);
}
// -- ini_category_consumer ----------------------------------------------------
ini_category_consumer::ini_category_consumer(ini_consumer* parent,
std::string category)
: super(parent), category_(std::move(category)) {
CAF_ASSERT(parent_ != nullptr);
}
ini_category_consumer::ini_category_consumer(ini_category_consumer&& other)
: super(other.parent()),
category_(std::move(other.category_)),
xs_(std::move(other.xs_)),
current_key(std::move(other.current_key)) {
CAF_ASSERT(parent_ != nullptr);
}
void ini_category_consumer::end_map() {
parent_->value_impl(config_value{std::move(xs_)});
}
void ini_category_consumer::key(std::string name) {
current_key = std::move(name);
}
void ini_category_consumer::value_impl(config_value&& x) {
// See whether there's an config_option associated to this category and key.
auto opt = dparent()->options_.qualified_name_lookup(category_, current_key);
if (opt == nullptr) {
// Simply store in config if no option was found.
xs_.emplace(std::move(current_key), std::move(x));
} else {
// Perform a type check to see whether this is a valid input.
if (opt->check(x) == none) {
opt->store(x);
xs_.emplace(std::move(current_key), std::move(x));
} else {
dparent()->warnings_.emplace_back(make_error(pec::type_mismatch));
}
}
}
ini_consumer* ini_category_consumer::dparent() {
// Safe, because our constructor only accepts ini_consumer parents.
return static_cast<ini_consumer*>(parent());
}
// -- ini_consumer -------------------------------------------------------------
ini_consumer::ini_consumer(const config_option_set& options, settings& cfg)
: options_(options), cfg_(cfg), current_key_("global") {
// nop
}
ini_category_consumer ini_consumer::begin_map() {
return {this, current_key_};
}
void ini_consumer::key(std::string name) {
current_key_ = std::move(name);
}
void ini_consumer::value_impl(config_value&& x) {
using dict_type = config_value::dictionary;
auto dict = get_if<dict_type>(&x);
if (dict == nullptr) {
warnings_.emplace_back(
make_error(pec::type_mismatch, "expected a dictionary at top level"));
return;
}
if (current_key_ != "global") {
auto& dst = cfg_.emplace(current_key_, dict_type{}).first->second;
if (dict != nullptr && !dict->empty()
&& holds_alternative<dict_type>(dst)) {
auto& dst_dict = get<dict_type>(dst);
// We need to "merge" values into the destination, because it can already
// contain any number of unrelated entries.
for (auto& entry : *dict)
dst_dict.insert_or_assign(entry.first, std::move(entry.second));
}
} else {
std::string prev_key;
swap(current_key_, prev_key);
for (auto& entry : *dict) {
if (holds_alternative<dict_type>(entry.second)) {
// Recurse into top-level maps.
current_key_ = std::move(entry.first);
value_impl(std::move(entry.second));
} else {
cfg_.insert_or_assign(entry.first, std::move(entry.second));
}
}
swap(prev_key, current_key_);
}
}
} // namespace caf::detail
......@@ -55,7 +55,7 @@ void await_all_locals_down(actor_system& sys, std::initializer_list<actor> xs) {
ys.push_back(x);
}
// Don't block when using the test coordinator.
if (auto policy = get_if<std::string>(&sys.config(), "scheduler.policy");
if (auto policy = get_if<std::string>(&sys.config(), "caf.scheduler.policy");
policy && *policy != "testing")
self->wait_for(ys);
}
......
......@@ -78,7 +78,7 @@ inbound_path::inbound_path(stream_manager_ptr mgr_ptr, stream_slots id,
<< detail::global_meta_object(in_type)->type_name
<< "at slot" << id.receiver << "from" << hdl);
if (auto str = get_if<std::string>(&self()->system().config(),
"stream.credit-policy")) {
"caf.stream.credit-policy")) {
if (*str == "testing")
controller_.reset(new detail::test_credit_controller(self()));
else if (*str == "size")
......
......@@ -283,7 +283,7 @@ logger* logger::current_logger() {
bool logger::accepts(unsigned level, string_view cname) {
if (level > cfg_.verbosity)
return false;
return !std::any_of(component_blacklist.begin(), component_blacklist.end(),
return std::none_of(global_filter_.begin(), global_filter_.end(),
[=](string_view name) { return name == cname; });
}
......@@ -302,51 +302,48 @@ logger::~logger() {
void logger::init(actor_system_config& cfg) {
CAF_IGNORE_UNUSED(cfg);
namespace lg = defaults::logger;
using std::string;
using string_list = std::vector<std::string>;
auto blacklist = get_if<string_list>(&cfg, "logger.component-blacklist");
if (blacklist)
component_blacklist = move_if_optional(blacklist);
// Parse the configured log level. We only store a string_view to the
// verbosity levels, so we make sure we actually get a string pointer here
// (and not an optional<string>).
const std::string* verbosity = get_if<std::string>(&cfg, "logger.verbosity");
auto set_level = [&](auto& var, auto var_default, string_view var_key) {
// User-provided overrides have the highest priority.
if (const std::string* var_override = get_if<std::string>(&cfg, var_key)) {
var = *var_override;
return;
}
// If present, "logger.verbosity" overrides the defaults for both file and
// console verbosity level.
if (verbosity) {
var = *verbosity;
return;
}
var = var_default;
auto get_verbosity = [&cfg](string_view key) -> unsigned {
if (auto str = get_if<string>(&cfg, key))
return to_level_int(*str);
return CAF_LOG_LEVEL_QUIET;
};
auto read_filter = [&cfg](string_list& var, string_view key) {
if (auto lst = get_if<string_list>(&cfg, key))
var = std::move(*lst);
};
string_view file_str;
string_view console_str;
set_level(file_str, lg::file_verbosity, "logger.file-verbosity");
set_level(console_str, lg::console_verbosity, "logger.console-verbosity");
cfg_.file_verbosity = to_level_int(file_str);
cfg_.console_verbosity = to_level_int(console_str);
cfg_.file_verbosity = get_verbosity("caf.logger.file.verbosity");
cfg_.console_verbosity = get_verbosity("caf.logger.console.verbosity");
cfg_.verbosity = std::max(cfg_.file_verbosity, cfg_.console_verbosity);
if (cfg_.verbosity == CAF_LOG_LEVEL_QUIET)
return;
if (cfg_.file_verbosity > CAF_LOG_LEVEL_QUIET
&& cfg_.console_verbosity > CAF_LOG_LEVEL_QUIET) {
read_filter(file_filter_, "caf.logger.file.excluded-components");
read_filter(console_filter_, "caf.logger.console.excluded-components");
std::sort(file_filter_.begin(), file_filter_.end());
std::sort(console_filter_.begin(), console_filter_.end());
std::set_union(file_filter_.begin(), file_filter_.end(),
console_filter_.begin(), console_filter_.end(),
std::back_inserter(global_filter_));
} else if (cfg_.file_verbosity > CAF_LOG_LEVEL_QUIET) {
read_filter(file_filter_, "caf.logger.file.excluded-components");
global_filter_ = file_filter_;
} else {
read_filter(console_filter_, "caf.logger.console.excluded-components");
global_filter_ = console_filter_;
}
// Parse the format string.
file_format_ =
parse_format(get_or(cfg, "logger.file-format", lg::file_format));
console_format_ = parse_format(get_or(cfg,"logger.console-format",
lg::console_format));
file_format_
= parse_format(get_or(cfg, "caf.logger.file.format", lg::file::format));
console_format_ = parse_format(
get_or(cfg, "caf.logger.console.format", lg::console::format));
// Set flags.
if (get_or(cfg, "logger.inline-output", false))
if (get_or(cfg, "caf.logger.inline-output", false))
cfg_.inline_output = true;
auto con = get_or(cfg, "logger.console", lg::console);
if (con == "colored") {
cfg_.console_coloring = true;
} else if (con != "uncolored") {
// Disable console output if neither 'colored' nor 'uncolored' are present.
cfg_.console_verbosity = CAF_LOG_LEVEL_QUIET;
cfg_.verbosity = cfg_.file_verbosity;
}
// If not set to `false`, CAF enables colored output when writing to TTYs.
cfg_.console_coloring = get_or(cfg, "caf.logger.console.colored", true);
}
bool logger::open_file() {
......@@ -530,13 +527,18 @@ void logger::run() {
void logger::handle_file_event(const event& x) {
// Print to file if available.
if (file_ && x.level <= file_verbosity())
if (file_ && x.level <= file_verbosity()
&& none_of(file_filter_.begin(), file_filter_.end(),
[&x](string_view name) { return name == x.category_name; }))
render(file_, file_format_, x);
}
void logger::handle_console_event(const event& x) {
if (x.level > console_verbosity())
return;
if (std::any_of(console_filter_.begin(), console_filter_.end(),
[&x](string_view name) { return name == x.category_name; }))
return;
if (cfg_.console_coloring) {
switch (x.level) {
default:
......@@ -572,21 +574,20 @@ void logger::handle_event(const event& x) {
void logger::log_first_line() {
auto e = CAF_LOG_MAKE_EVENT(0, CAF_LOG_COMPONENT, CAF_LOG_LEVEL_DEBUG, "");
auto make_message = [&](string_view config_name, std::string default_value) {
std::string msg = "level = ";
msg += get_or(system_.config(), config_name, default_value);
auto make_message = [&](int level, const auto& filter) {
auto lvl_str = log_level_name[level];
std::string msg = "verbosity = ";
msg.insert(msg.end(), lvl_str.begin(), lvl_str.end());
msg += ", node = ";
msg += to_string(system_.node());
msg += ", component-blacklist = ";
msg += deep_to_string(component_blacklist);
msg += ", excluded-components = ";
msg += deep_to_string(filter);
return msg;
};
namespace lg = defaults::logger;
e.message = make_message("logger.file-verbosity",
to_string(lg::file_verbosity));
e.message = make_message(cfg_.file_verbosity, file_filter_);
handle_file_event(e);
e.message = make_message("logger.console-verbosity",
to_string(lg::console_verbosity));
e.message = make_message(cfg_.console_verbosity, console_filter_);
handle_console_event(e);
}
......@@ -599,8 +600,8 @@ void logger::start() {
parent_thread_ = std::this_thread::get_id();
if (verbosity() == CAF_LOG_LEVEL_QUIET)
return;
file_name_ = get_or(system_.config(), "logger.file-name",
defaults::logger::file_name);
file_name_ = get_or(system_.config(), "caf.logger.file.path",
defaults::logger::file::path);
if (file_name_.empty()) {
// No need to continue if console and log file are disabled.
if (console_verbosity() == CAF_LOG_LEVEL_QUIET)
......
......@@ -247,8 +247,9 @@ void abstract_coordinator::start() {
void abstract_coordinator::init(actor_system_config& cfg) {
namespace sr = defaults::scheduler;
max_throughput_ = get_or(cfg, "scheduler.max-throughput", sr::max_throughput);
if (auto num_workers = get_if<size_t>(&cfg, "scheduler.max-threads"))
max_throughput_ = get_or(cfg, "caf.scheduler.max-throughput",
sr::max_throughput);
if (auto num_workers = get_if<size_t>(&cfg, "caf.scheduler.max-threads"))
num_workers_ = *num_workers;
else
num_workers_ = default_thread_count();
......
......@@ -109,7 +109,7 @@ behavior tester(event_based_actor* self, const actor& aut) {
struct config : actor_system_config {
config() {
set("scheduler.policy", "testing");
set("caf.scheduler.policy", "testing");
}
};
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE detail.ini_consumer
#include "caf/detail/ini_consumer.hpp"
#include "caf/test/dsl.hpp"
#include "caf/detail/parser/read_ini.hpp"
using std::string;
using namespace caf;
// List-of-strings.
using ls = std::vector<std::string>;
namespace {
constexpr const string_view test_ini = R"(
is_server=true
port=4242
nodes=["sun", "venus", ]
[logger]
file-name = "foobar.ini" ; our file name
[scheduler] ; more settings
timing = 2us ; using microsecond resolution
)";
constexpr const string_view test_ini2 = R"(
is_server = true
logger = {
file-name = "foobar.ini"
}
port = 4242
scheduler = {
timing = 2us,
}
nodes = ["sun", "venus"]
)";
struct fixture {
config_option_set options;
settings config;
fixture() {
options.add<bool>("global", "is_server", "enables server mode")
.add<uint16_t>("global", "port", "sets local or remote port")
.add<ls>("global", "nodes", "list of remote nodes")
.add<string>("logger", "file-name", "log output file")
.add<int>("scheduler", "padding", "some integer")
.add<timespan>("scheduler", "timing", "some timespan");
}
};
} // namespace
CAF_TEST_FIXTURE_SCOPE(ini_consumer_tests, fixture)
CAF_TEST(ini_value_consumer) {
string_view str = R"("hello world")";
detail::ini_value_consumer consumer;
string_parser_state res{str.begin(), str.end()};
detail::parser::read_ini_value(res, consumer);
CAF_CHECK_EQUAL(res.code, pec::success);
CAF_CHECK_EQUAL(get<string>(consumer.result), "hello world");
}
CAF_TEST(ini_consumer) {
string_view str = test_ini;
detail::ini_consumer consumer{options, config};
string_parser_state res{str.begin(), str.end()};
detail::parser::read_ini(res, consumer);
CAF_CHECK_EQUAL(res.code, pec::success);
CAF_CHECK_EQUAL(get<bool>(config, "is_server"), true);
CAF_CHECK_EQUAL(get<uint16_t>(config, "port"), 4242u);
CAF_CHECK_EQUAL(get<ls>(config, "nodes"), ls({"sun", "venus"}));
CAF_CHECK_EQUAL(get<string>(config, "logger.file-name"), "foobar.ini");
CAF_MESSAGE(config);
CAF_CHECK_EQUAL(get<timespan>(config, "scheduler.timing"), timespan(2000));
}
CAF_TEST(simplified syntax) {
CAF_MESSAGE("read test_ini");
{
detail::ini_consumer consumer{options, config};
string_parser_state res{test_ini.begin(), test_ini.end()};
detail::parser::read_ini(res, consumer);
CAF_CHECK_EQUAL(res.code, pec::success);
}
settings config2;
CAF_MESSAGE("read test_ini2");
{
detail::ini_consumer consumer{options, config2};
string_parser_state res{test_ini2.begin(), test_ini2.end()};
detail::parser::read_ini(res, consumer);
CAF_CHECK_EQUAL(res.code, pec::success);
}
CAF_CHECK_EQUAL(config, config2);
}
CAF_TEST_FIXTURE_SCOPE_END()
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE detail.parser.read_ini
#include "caf/detail/parser/read_ini.hpp"
#include "caf/test/dsl.hpp"
#include <string>
#include <vector>
#include "caf/config_value.hpp"
#include "caf/parser_state.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
using namespace caf;
namespace {
using log_type = std::vector<std::string>;
struct test_consumer {
log_type log;
test_consumer() = default;
test_consumer(const test_consumer&) = delete;
test_consumer& operator=(const test_consumer&) = delete;
test_consumer& begin_map() {
log.emplace_back("{");
return *this;
}
void end_map() {
log.emplace_back("}");
}
test_consumer& begin_list() {
log.emplace_back("[");
return *this;
}
void end_list() {
log.emplace_back("]");
}
void key(std::string name) {
add_entry("key: ", std::move(name));
}
template <class T>
void value(T x) {
config_value cv{std::move(x)};
std::string entry = "value (";
entry += cv.type_name();
entry += "): ";
entry += to_string(cv);
log.emplace_back(std::move(entry));
}
void add_entry(const char* prefix, std::string str) {
str.insert(0, prefix);
log.emplace_back(std::move(str));
}
};
struct fixture {
expected<log_type> parse(string_view str, bool expect_success = true) {
test_consumer f;
string_parser_state res{str.begin(), str.end()};
detail::parser::read_ini(res, f);
if ((res.code == pec::success) != expect_success) {
CAF_MESSAGE("unexpected parser result state: " << res.code);
CAF_MESSAGE("input remainder: " << std::string(res.i, res.e));
}
return std::move(f.log);
}
};
template <class... Ts>
log_type make_log(Ts&&... xs) {
return log_type{std::forward<Ts>(xs)...};
}
// Tests basic functionality.
constexpr const string_view ini0 = R"(
[1group]
1value=321
[_foo]
_bar=11
[logger]
padding= 10
file-name = "foobar.ini" ; our file name
[scheduler] ; more settings
timing = 2us ; using microsecond resolution
x_ =.123
some-bool=true
some-other-bool=false
some-list=[
; here we have some list entries
123,
1..3,
23 ; twenty-three!
,2..4..2,
"abc", ; some comment and a trailing comma
]
some-map{
; here we have some list entries
entry1=123,
entry2=23 ; twenty-three! btw, comma is not mandatory
entry3= "abc" , ; some comment and a trailing comma
}
[middleman]
preconnect=[<
tcp://localhost:8080
>,<udp://remotehost?trust=false>]
)";
// clang-format off
const auto ini0_log = make_log(
"key: 1group",
"{",
"key: 1value",
"value (integer): 321",
"}",
"key: _foo",
"{",
"key: _bar",
"value (integer): 11",
"}",
"key: logger",
"{",
"key: padding",
"value (integer): 10",
"key: file-name",
"value (string): \"foobar.ini\"",
"}",
"key: scheduler",
"{",
"key: timing",
"value (timespan): 2us",
"key: x_",
"value (real): " + deep_to_string(.123),
"key: some-bool",
"value (boolean): true",
"key: some-other-bool",
"value (boolean): false",
"key: some-list",
"[",
"value (integer): 123",
"value (integer): 1",
"value (integer): 2",
"value (integer): 3",
"value (integer): 23",
"value (integer): 2",
"value (integer): 4",
"value (string): \"abc\"",
"]",
"key: some-map",
"{",
"key: entry1",
"value (integer): 123",
"key: entry2",
"value (integer): 23",
"key: entry3",
"value (string): \"abc\"",
"}",
"}",
"key: middleman",
"{",
"key: preconnect",
"[",
"value (uri): tcp://localhost:8080",
"value (uri): udp://remotehost?trust=false",
"]",
"}"
);
// clang-format on
// Tests nested parameters.
constexpr const string_view ini1 = R"(
foo {
bar = {
value1 = 1
}
value2 = 2
}
[bar.foo]
value3 = 3
)";
// clang-format off
const auto ini1_log = make_log(
"key: global",
"{",
"key: foo",
"{",
"key: bar",
"{",
"key: value1",
"value (integer): 1",
"}",
"key: value2",
"value (integer): 2",
"}",
"}",
"key: bar",
"{",
"key: foo",
"{",
"key: value3",
"value (integer): 3",
"}",
"}"
);
// clang-format on
constexpr const string_view ini2 = "#";
const auto ini2_log = make_log();
constexpr const string_view ini3 = "; foobar\n!";
const auto ini3_log = make_log();
} // namespace
CAF_TEST_FIXTURE_SCOPE(read_ini_tests, fixture)
CAF_TEST(empty inis) {
CAF_CHECK_EQUAL(parse(";foo"), make_log());
CAF_CHECK_EQUAL(parse(""), make_log());
CAF_CHECK_EQUAL(parse(" "), make_log());
CAF_CHECK_EQUAL(parse(" \n "), make_log());
CAF_CHECK_EQUAL(parse(";hello\n;world"), make_log());
}
CAF_TEST(section with valid key - value pairs) {
CAF_CHECK_EQUAL(parse("[foo]"), make_log("key: foo", "{", "}"));
CAF_CHECK_EQUAL(parse(" [foo]"), make_log("key: foo", "{", "}"));
CAF_CHECK_EQUAL(parse(" [ foo] "), make_log("key: foo", "{", "}"));
CAF_CHECK_EQUAL(parse(" [ foo ] "), make_log("key: foo", "{", "}"));
CAF_CHECK_EQUAL(parse("\n[a-b];foo\n;bar"), make_log("key: a-b", "{", "}"));
CAF_CHECK_EQUAL(parse(ini0), ini0_log);
CAF_CHECK_EQUAL(parse(ini1), ini1_log);
}
CAF_TEST(invalid inis) {
CAF_CHECK_EQUAL(parse(ini2), ini2_log);
CAF_CHECK_EQUAL(parse(ini3), ini3_log);
}
CAF_TEST(integer keys are legal in INI syntax) {
static constexpr string_view ini = R"__(
[foo.bar]
1 = 10
2 = 20
)__";
// clang-format off
auto log = make_log(
"key: foo",
"{",
"key: bar",
"{",
"key: 1",
"value (integer): 10",
"key: 2",
"value (integer): 20",
"}",
"}"
);
// clang-format on
CAF_CHECK_EQUAL(parse(ini), log);
}
CAF_TEST(integer keys are legal in config syntax) {
static constexpr string_view ini = R"__(
foo {
bar {
1 = 10
2 = 20
}
}
)__";
// clang-format off
auto log = make_log(
"key: global",
"{",
"key: foo",
"{",
"key: bar",
"{",
"key: 1",
"value (integer): 10",
"key: 2",
"value (integer): 20",
"}",
"}",
"}"
);
// clang-format on
CAF_CHECK_EQUAL(parse(ini), log);
}
CAF_TEST_FIXTURE_SCOPE_END()
......@@ -61,7 +61,9 @@ namespace {
struct fixture {
fixture() {
cfg.set("scheduler.policy", "testing");
cfg.set("caf.scheduler.policy", "testing");
cfg.set("caf.logger.file.verbosity", "debug");
cfg.set("caf.logger.file.path", "");
}
void add(logger::field_type kind) {
......@@ -161,10 +163,7 @@ CAF_TEST(parse_default_format_strings) {
add(logger::message_field);
add(logger::newline_field);
CAF_CHECK_EQUAL(logger::parse_format(file_format), lf);
#if CAF_LOG_LEVEL >= 0
// Not parsed when compiling without logging enabled.
CAF_CHECK_EQUAL(sys.logger().file_format(), lf);
#endif
}
CAF_TEST(rendering) {
......
......@@ -530,7 +530,7 @@ struct fixture {
if (auto err = cfg.parse(caf::test::engine::argc(),
caf::test::engine::argv()))
CAF_FAIL("parsing the config failed: " << to_string(err));
cfg.set("scheduler.policy", "testing");
cfg.set("caf.scheduler.policy", "testing");
return cfg;
}
......
......@@ -116,7 +116,7 @@ CAF_TEST_FIXTURE_SCOPE(counting_hook, fixture<counting_thread_hook>)
CAF_TEST(counting_system_without_actor) {
assumed_init_calls = 1;
auto fallback = scheduler::abstract_coordinator::default_thread_count();
assumed_thread_count = get_or(cfg, "scheduler.max-threads", fallback)
assumed_thread_count = get_or(cfg, "caf.scheduler.max-threads", fallback)
+ 1; // caf.clock
auto& sched = sys.scheduler();
if (sched.detaches_utility_actors())
......@@ -126,7 +126,7 @@ CAF_TEST(counting_system_without_actor) {
CAF_TEST(counting_system_with_actor) {
assumed_init_calls = 1;
auto fallback = scheduler::abstract_coordinator::default_thread_count();
assumed_thread_count = get_or(cfg, "scheduler.max-threads", fallback)
assumed_thread_count = get_or(cfg, "caf.scheduler.max-threads", fallback)
+ 2; // caf.clock and detached actor
auto& sched = sys.scheduler();
if (sched.detaches_utility_actors())
......
......@@ -44,7 +44,7 @@ instance::instance(abstract_broker* parent, callee& lstnr)
: tbl_(parent), this_node_(parent->system().node()), callee_(lstnr) {
CAF_ASSERT(this_node_ != none);
size_t workers;
if (auto workers_cfg = get_if<size_t>(&config(), "middleman.workers"))
if (auto workers_cfg = get_if<size_t>(&config(), "caf.middleman.workers"))
workers = *workers_cfg;
else
workers = std::min(3u, std::thread::hardware_concurrency() / 4u) + 1;
......@@ -231,7 +231,8 @@ void instance::write_server_handshake(execution_unit* ctx, byte_buffer& out_buf,
auto writer = make_callback([&](binary_serializer& sink) {
using string_list = std::vector<std::string>;
string_list app_ids;
if (auto ids = get_if<string_list>(&config(), "middleman.app-identifiers"))
if (auto ids = get_if<string_list>(&config(),
"caf.middleman.app-identifiers"))
app_ids = std::move(*ids);
else
app_ids.emplace_back(to_string(defaults::middleman::app_identifier));
......@@ -323,7 +324,8 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
}
// Check the application ID.
string_list whitelist;
if (auto ls = get_if<string_list>(&config(), "middleman.app-identifiers"))
if (auto ls = get_if<string_list>(&config(),
"caf.middleman.app-identifiers"))
whitelist = std::move(*ls);
else
whitelist.emplace_back(to_string(defaults::middleman::app_identifier));
......
......@@ -105,7 +105,7 @@ behavior basp_broker::make_behavior() {
set_down_handler([](local_actor* ptr, down_msg& x) {
static_cast<basp_broker*>(ptr)->handle_down_msg(x);
});
if (get_or(config(), "middleman.enable-automatic-connections", false)) {
if (get_or(config(), "caf.middleman.enable-automatic-connections", false)) {
CAF_LOG_DEBUG("enable automatic connections");
// open a random port and store a record for our peers how to
// connect to this broker directly in the configuration server
......@@ -120,7 +120,7 @@ behavior basp_broker::make_behavior() {
}
automatic_connections = true;
}
auto heartbeat_interval = get_or(config(), "middleman.heartbeat-interval",
auto heartbeat_interval = get_or(config(), "caf.middleman.heartbeat-interval",
defaults::middleman::heartbeat_interval);
if (heartbeat_interval > 0) {
CAF_LOG_DEBUG("enable heartbeat" << CAF_ARG(heartbeat_interval));
......@@ -585,7 +585,7 @@ void basp_broker::learned_new_node_indirectly(const node_id& nid) {
// connection to the routing table; hence, spawning our helper here exactly
// once and there is no need to track in-flight connection requests.
using namespace detail;
auto tmp = get_or(config(), "middleman.attach-utility-actors", false)
auto tmp = get_or(config(), "caf.middleman.attach-utility-actors", false)
? system().spawn<hidden>(connection_helper, this)
: system().spawn<detached + hidden>(connection_helper, this);
auto sender = actor_cast<strong_actor_ptr>(tmp);
......
......@@ -87,7 +87,7 @@ void middleman::init_global_meta_objects() {
}
actor_system::module* middleman::make(actor_system& sys, detail::type_list<>) {
auto impl = get_or(sys.config(), "middleman.network-backend",
auto impl = get_or(sys.config(), "caf.middleman.network-backend",
defaults::middleman::network_backend);
if (impl == "testing")
return new mm_impl<network::test_multiplexer>(sys);
......@@ -272,7 +272,7 @@ strong_actor_ptr middleman::remote_lookup(std::string name,
void middleman::start() {
CAF_LOG_TRACE("");
// Launch backend.
if (!get_or(config(), "middleman.manual-multiplexing", false))
if (!get_or(config(), "caf.middleman.manual-multiplexing", false))
backend_supervisor_ = backend().make_supervisor();
// The only backend that returns a `nullptr` by default is the
// `test_multiplexer` which does not have its own thread but uses the main
......@@ -332,7 +332,7 @@ void middleman::stop() {
}
}
});
if (!get_or(config(), "middleman.manual-multiplexing", false)) {
if (!get_or(config(), "caf.middleman.manual-multiplexing", false)) {
backend_supervisor_.reset();
if (thread_.joinable())
thread_.join();
......@@ -343,7 +343,7 @@ void middleman::stop() {
named_brokers_.clear();
scoped_actor self{system(), true};
self->send_exit(manager_, exit_reason::kill);
if (!get_or(config(), "middleman.attach-utility-actors", false))
if (!get_or(config(), "caf.middleman.attach-utility-actors", false))
self->wait_for(manager_);
destroy(manager_);
}
......@@ -351,11 +351,11 @@ void middleman::stop() {
void middleman::init(actor_system_config& cfg) {
// Note: logging is not available at this stage.
// Never detach actors when using the testing multiplexer.
auto network_backend = get_or(cfg, "middleman.network-backend",
auto network_backend = get_or(cfg, "caf.middleman.network-backend",
defaults::middleman::network_backend);
if (network_backend == "testing") {
cfg.set("middleman.attach-utility-actors", true)
.set("middleman.manual-multiplexing", true);
cfg.set("caf.middleman.attach-utility-actors", true)
.set("caf.middleman.manual-multiplexing", true);
}
// Add remote group module to config.
struct remote_groups : group_module {
......
......@@ -31,7 +31,7 @@
namespace caf::io {
middleman_actor make_middleman_actor(actor_system& sys, actor db) {
return get_or(sys.config(), "middleman.attach-utility-actors", false)
return get_or(sys.config(), "caf.middleman.attach-utility-actors", false)
? sys.spawn<middleman_actor_impl, hidden>(std::move(db))
: sys.spawn<middleman_actor_impl, detached + hidden>(std::move(db));
}
......
......@@ -39,7 +39,7 @@ datagram_handler::datagram_handler(default_multiplexer& backend_ref,
native_socket sockfd)
: event_handler(backend_ref, sockfd),
max_consecutive_reads_(get_or(backend().system().config(),
"middleman.max-consecutive-reads",
"caf.middleman.max-consecutive-reads",
defaults::middleman::max_consecutive_reads)),
max_datagram_size_(receive_buffer_size),
rd_buf_(receive_buffer_size),
......
......@@ -589,8 +589,8 @@ void default_multiplexer::init() {
}
#endif
namespace sr = defaults::scheduler;
max_throughput_
= get_or(system().config(), "scheduler.max-throughput", sr::max_throughput);
max_throughput_ = get_or(system().config(), "caf.scheduler.max-throughput",
sr::max_throughput);
}
bool default_multiplexer::poll_once(bool block) {
......
......@@ -31,7 +31,7 @@ namespace caf::io::network {
stream::stream(default_multiplexer& backend_ref, native_socket sockfd)
: event_handler(backend_ref, sockfd),
max_consecutive_reads_(get_or(backend().system().config(),
"middleman.max-consecutive-reads",
"caf.middleman.max-consecutive-reads",
defaults::middleman::max_consecutive_reads)),
read_threshold_(1),
collected_(0),
......
......@@ -105,10 +105,10 @@ class fixture {
public:
fixture(bool autoconn = false)
: sys(cfg.load<io::middleman, network::test_multiplexer>()
.set("middleman.enable-automatic-connections", autoconn)
.set("middleman.workers", size_t{0})
.set("scheduler.policy", autoconn ? "testing" : "stealing")
.set("middleman.attach-utility-actors", autoconn)) {
.set("caf.middleman.enable-automatic-connections", autoconn)
.set("caf.middleman.workers", size_t{0})
.set("caf.scheduler.policy", autoconn ? "testing" : "stealing")
.set("caf.middleman.attach-utility-actors", autoconn)) {
app_ids.emplace_back(to_string(defaults::middleman::app_identifier));
auto& mm = sys.middleman();
mpx_ = dynamic_cast<network::test_multiplexer*>(&mm.backend());
......
......@@ -104,7 +104,7 @@ void manager::stop() {
CAF_LOG_TRACE("");
scoped_actor self{system(), true};
self->send_exit(manager_, exit_reason::kill);
if (!get_or(config(), "middleman.attach-utility-actors", false))
if (!get_or(config(), "caf.middleman.attach-utility-actors", false))
self->wait_for(manager_);
manager_ = nullptr;
}
......
......@@ -284,7 +284,7 @@ private:
} // namespace
io::middleman_actor make_middleman_actor(actor_system& sys, actor db) {
return !get_or(sys.config(), "middleman.attach-utility-actors", false)
return !get_or(sys.config(), "caf.middleman.attach-utility-actors", false)
? sys.spawn<middleman_actor_impl, detached + hidden>(std::move(db))
: sys.spawn<middleman_actor_impl, hidden>(std::move(db));
}
......
......@@ -54,9 +54,9 @@ public:
config() {
load<io::middleman>();
load<openssl::manager>();
set("middleman.manual-multiplexing", true);
set("middleman.attach-utility-actors", true);
set("scheduler.policy", "testing");
set("caf.middleman.manual-multiplexing", true);
set("caf.middleman.attach-utility-actors", true);
set("caf.scheduler.policy", "testing");
}
static std::string data_dir() {
......
......@@ -45,7 +45,7 @@ public:
// OpenSSL to buffer data internally and report "pending" data after a read
// operation. This will trigger `must_read_more` in the SSL read policy
// with high probability.
set("middleman.max-consecutive-reads", 1);
set("caf.middleman.max-consecutive-reads", 1);
}
};
......
......@@ -674,16 +674,15 @@ public:
// -- constructors, destructors, and assignment operators --------------------
static Config& init_config(Config& cfg) {
cfg.set("logger.file-verbosity", "quiet");
if (auto err = cfg.parse(caf::test::engine::argc(),
caf::test::engine::argv()))
CAF_FAIL("failed to parse config: " << to_string(err));
cfg.set("scheduler.policy", "testing");
cfg.set("logger.inline-output", true);
cfg.set("middleman.network-backend", "testing");
cfg.set("middleman.manual-multiplexing", true);
cfg.set("middleman.workers", size_t{0});
cfg.set("stream.credit-policy", "testing");
cfg.set("caf.scheduler.policy", "testing");
cfg.set("caf.logger.inline-output", true);
cfg.set("caf.middleman.network-backend", "testing");
cfg.set("caf.middleman.manual-multiplexing", true);
cfg.set("caf.middleman.workers", size_t{0});
cfg.set("caf.stream.credit-policy", "testing");
return cfg;
}
......
This diff is collapsed.
......@@ -176,10 +176,10 @@ void bootstrap(actor_system& system, const string& wdir,
std::ostringstream oss;
oss << cmd;
if (slave.cpu_slots > 0)
oss << " --caf#scheduler.max-threads=" << slave.cpu_slots;
oss << " --caf#slave-mode"
<< " --caf#slave-name=" << slave.host
<< " --caf#bootstrap-node=";
oss << " --caf.scheduler.max-threads=" << slave.cpu_slots;
oss << " --caf.slave-mode"
<< " --caf.slave-name=" << slave.host
<< " --caf.bootstrap-node=";
bool is_first = true;
interfaces::traverse({protocol::ipv4, protocol::ipv6},
[&](const char*, protocol::network,
......@@ -216,7 +216,7 @@ void bootstrap(actor_system& system, const string& wdir,
}
// run (and wait for) master
std::ostringstream oss;
oss << cmd << " --caf#slave-nodes=" << slaveslist << " " << join(args, " ");
oss << cmd << " --caf.slave-nodes=" << slaveslist << " " << join(args, " ");
run_ssh(system, wdir, oss.str(), master.host);
}
......
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