Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
a6b6130b
Commit
a6b6130b
authored
Jul 07, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'issue/1116'
Close #1116.
parents
13b5d670
c6f9177e
Changes
37
Show whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
353 additions
and
1630 deletions
+353
-1630
CHANGELOG.md
CHANGELOG.md
+5
-8
examples/caf-application.conf
examples/caf-application.conf
+82
-83
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+0
-3
libcaf_core/caf/actor_system_config.hpp
libcaf_core/caf/actor_system_config.hpp
+5
-14
libcaf_core/caf/defaults.hpp
libcaf_core/caf/defaults.hpp
+13
-27
libcaf_core/caf/detail/ini_consumer.hpp
libcaf_core/caf/detail/ini_consumer.hpp
+0
-214
libcaf_core/caf/detail/parser/read_ini.hpp
libcaf_core/caf/detail/parser/read_ini.hpp
+0
-346
libcaf_core/caf/logger.hpp
libcaf_core/caf/logger.hpp
+9
-2
libcaf_core/src/actor_system.cpp
libcaf_core/src/actor_system.cpp
+1
-1
libcaf_core/src/actor_system_config.cpp
libcaf_core/src/actor_system_config.cpp
+53
-109
libcaf_core/src/config_option_set.cpp
libcaf_core/src/config_option_set.cpp
+1
-3
libcaf_core/src/detail/ini_consumer.cpp
libcaf_core/src/detail/ini_consumer.cpp
+0
-198
libcaf_core/src/group_manager.cpp
libcaf_core/src/group_manager.cpp
+1
-1
libcaf_core/src/inbound_path.cpp
libcaf_core/src/inbound_path.cpp
+1
-1
libcaf_core/src/logger.cpp
libcaf_core/src/logger.cpp
+53
-52
libcaf_core/src/scheduler/abstract_coordinator.cpp
libcaf_core/src/scheduler/abstract_coordinator.cpp
+3
-2
libcaf_core/test/actor_lifetime.cpp
libcaf_core/test/actor_lifetime.cpp
+1
-1
libcaf_core/test/detail/ini_consumer.cpp
libcaf_core/test/detail/ini_consumer.cpp
+0
-118
libcaf_core/test/detail/parser/read_ini.cpp
libcaf_core/test/detail/parser/read_ini.cpp
+0
-324
libcaf_core/test/logger.cpp
libcaf_core/test/logger.cpp
+3
-4
libcaf_core/test/native_streaming_classes.cpp
libcaf_core/test/native_streaming_classes.cpp
+1
-1
libcaf_core/test/thread_hook.cpp
libcaf_core/test/thread_hook.cpp
+2
-2
libcaf_io/src/io/basp/instance.cpp
libcaf_io/src/io/basp/instance.cpp
+5
-3
libcaf_io/src/io/basp_broker.cpp
libcaf_io/src/io/basp_broker.cpp
+3
-3
libcaf_io/src/io/middleman.cpp
libcaf_io/src/io/middleman.cpp
+7
-7
libcaf_io/src/io/middleman_actor.cpp
libcaf_io/src/io/middleman_actor.cpp
+1
-1
libcaf_io/src/io/network/datagram_handler.cpp
libcaf_io/src/io/network/datagram_handler.cpp
+1
-1
libcaf_io/src/io/network/default_multiplexer.cpp
libcaf_io/src/io/network/default_multiplexer.cpp
+2
-2
libcaf_io/src/io/network/stream.cpp
libcaf_io/src/io/network/stream.cpp
+1
-1
libcaf_io/test/io/basp_broker.cpp
libcaf_io/test/io/basp_broker.cpp
+4
-4
libcaf_openssl/src/openssl/manager.cpp
libcaf_openssl/src/openssl/manager.cpp
+1
-1
libcaf_openssl/src/openssl/middleman_actor.cpp
libcaf_openssl/src/openssl/middleman_actor.cpp
+1
-1
libcaf_openssl/test/openssl/authentication.cpp
libcaf_openssl/test/openssl/authentication.cpp
+3
-3
libcaf_openssl/test/openssl/remote_actor.cpp
libcaf_openssl/test/openssl/remote_actor.cpp
+1
-1
libcaf_test/caf/test/dsl.hpp
libcaf_test/caf/test/dsl.hpp
+6
-7
manual/ConfiguringActorApplications.rst
manual/ConfiguringActorApplications.rst
+78
-76
tools/caf-run.cpp
tools/caf-run.cpp
+5
-5
No files found.
CHANGELOG.md
View file @
a6b6130b
...
...
@@ -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
...
...
examples/caf-application.conf
View file @
a6b6130b
# 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
=
100
ms
# 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
=
50
us
# frequency of steal attempts during relaxed polling
relaxed
-
steal
-
interval
=
1
# sleep interval between poll attempts
relaxed
-
sleep
-
duration
=
10
ms
}
# 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
=
0
ms
# configures whether the MM attaches its internal utility actors to the
# 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
=
50
us
# Frequency of steal attempts during relaxed polling.
relaxed
-
steal
-
interval
=
1
# Sleep interval between poll attempts.
relaxed
-
sleep
-
duration
=
10
ms
}
# 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
=
0
ms
# 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
=[]
# 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 = []
# }
}
}
libcaf_core/CMakeLists.txt
View file @
a6b6130b
...
...
@@ -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
...
...
libcaf_core/caf/actor_system_config.hpp
View file @
a6b6130b
...
...
@@ -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
/// `c
af-application.ini` (deprecated) if `c
onfig_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.
...
...
libcaf_core/caf/defaults.hpp
View file @
a6b6130b
...
...
@@ -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
{
...
...
libcaf_core/caf/detail/ini_consumer.hpp
deleted
100644 → 0
View file @
13b5d670
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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
libcaf_core/caf/detail/parser/read_ini.hpp
deleted
100644 → 0
View file @
13b5d670
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 <ctype.h>
#include <stack>
#include "caf/config.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/read_bool.hpp"
#include "caf/detail/parser/read_number_or_timespan.hpp"
#include "caf/detail/parser/read_string.hpp"
#include "caf/detail/parser/read_uri.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/pec.hpp"
#include "caf/uri_builder.hpp"
CAF_PUSH_UNUSED_LABEL_WARNING
#include "caf/detail/parser/fsm.hpp"
namespace
caf
::
detail
::
parser
{
// Example input:
//
// [section1]
// value1 = 123
// value2 = "string"
// subsection1 = {
// value3 = 1.23
// value4 = 4e20
// }
// [section2]
// value5 = 'atom'
// value6 = [1, 'two', "three", {
// a = "b",
// b = "c",
// }]
//
template
<
class
State
,
class
Consumer
>
void
read_ini_comment
(
State
&
ps
,
Consumer
&&
)
{
// clang-format off
start
();
term_state
(
init
)
{
transition
(
done
,
'\n'
)
transition
(
init
)
}
term_state
(
done
)
{
// nop
}
fin
();
// clang-format on
}
template
<
class
State
,
class
Consumer
,
class
InsideList
=
std
::
false_type
>
void
read_ini_value
(
State
&
ps
,
Consumer
&&
consumer
,
InsideList
inside_list
=
{});
template
<
class
State
,
class
Consumer
>
void
read_ini_list
(
State
&
ps
,
Consumer
&&
consumer
)
{
// clang-format off
start
();
state
(
init
)
{
epsilon
(
before_value
)
}
state
(
before_value
)
{
transition
(
before_value
,
"
\t\n
"
)
transition
(
done
,
']'
,
consumer
.
end_list
())
fsm_epsilon
(
read_ini_comment
(
ps
,
consumer
),
before_value
,
';'
)
fsm_epsilon
(
read_ini_value
(
ps
,
consumer
,
std
::
true_type
{}),
after_value
)
}
state
(
after_value
)
{
transition
(
after_value
,
"
\t\n
"
)
transition
(
before_value
,
','
)
transition
(
done
,
']'
,
consumer
.
end_list
())
fsm_epsilon
(
read_ini_comment
(
ps
,
consumer
),
after_value
,
';'
)
}
term_state
(
done
)
{
// nop
}
fin
();
// clang-format on
}
template
<
class
State
,
class
Consumer
>
void
read_ini_map
(
State
&
ps
,
Consumer
&&
consumer
)
{
std
::
string
key
;
auto
alnum_or_dash
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'-'
||
x
==
'_'
;
};
// clang-format off
start
();
state
(
init
)
{
epsilon
(
await_key_name
)
}
state
(
await_key_name
)
{
transition
(
await_key_name
,
"
\t\n
"
)
fsm_epsilon
(
read_ini_comment
(
ps
,
consumer
),
await_key_name
,
';'
)
transition
(
read_key_name
,
alphanumeric_chars
,
key
=
ch
)
transition
(
done
,
'}'
,
consumer
.
end_map
())
}
// Reads a key of a "key=value" line.
state
(
read_key_name
)
{
transition
(
read_key_name
,
alnum_or_dash
,
key
+=
ch
)
epsilon
(
await_assignment
)
}
// Reads the assignment operator in a "key=value" line.
state
(
await_assignment
)
{
transition
(
await_assignment
,
"
\t
"
)
transition
(
await_value
,
'='
,
consumer
.
key
(
std
::
move
(
key
)))
epsilon
(
await_value
,
'{'
,
consumer
.
key
(
std
::
move
(
key
)))
}
// Reads the value in a "key=value" line.
state
(
await_value
)
{
transition
(
await_value
,
"
\t
"
)
fsm_epsilon
(
read_ini_value
(
ps
,
consumer
),
after_value
)
}
// Waits for end-of-line after reading a value
state
(
after_value
)
{
transition
(
after_value
,
"
\t
"
)
transition
(
had_newline
,
"
\n
"
)
transition
(
await_key_name
,
','
)
transition
(
done
,
'}'
,
consumer
.
end_map
())
fsm_epsilon
(
read_ini_comment
(
ps
,
consumer
),
had_newline
,
';'
)
}
// Allows users to skip the ',' for separating key/value pairs
state
(
had_newline
)
{
transition
(
had_newline
,
"
\t\n
"
)
transition
(
await_key_name
,
','
)
transition
(
done
,
'}'
,
consumer
.
end_map
())
fsm_epsilon
(
read_ini_comment
(
ps
,
consumer
),
had_newline
,
';'
)
epsilon
(
read_key_name
,
alnum_or_dash
)
}
term_state
(
done
)
{
//nop
}
fin
();
// clang-format on
}
template
<
class
State
,
class
Consumer
>
void
read_ini_uri
(
State
&
ps
,
Consumer
&&
consumer
)
{
uri_builder
builder
;
auto
g
=
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
consumer
.
value
(
builder
.
make
());
});
// clang-format off
start
();
state
(
init
)
{
transition
(
init
,
"
\t\n
"
)
transition
(
before_uri
,
'<'
)
}
state
(
before_uri
)
{
transition
(
before_uri
,
"
\t\n
"
)
fsm_epsilon
(
read_uri
(
ps
,
builder
),
after_uri
)
}
state
(
after_uri
)
{
transition
(
after_uri
,
"
\t\n
"
)
transition
(
done
,
'>'
)
}
term_state
(
done
)
{
// nop
}
fin
();
// clang-format on
}
template
<
class
State
,
class
Consumer
,
class
InsideList
>
void
read_ini_value
(
State
&
ps
,
Consumer
&&
consumer
,
InsideList
inside_list
)
{
// clang-format off
start
();
state
(
init
)
{
fsm_epsilon
(
read_string
(
ps
,
consumer
),
done
,
quote_marks
)
fsm_epsilon
(
read_number
(
ps
,
consumer
),
done
,
'.'
)
fsm_epsilon
(
read_bool
(
ps
,
consumer
),
done
,
"ft"
)
fsm_epsilon
(
read_number_or_timespan
(
ps
,
consumer
,
inside_list
),
done
,
"0123456789+-"
)
fsm_epsilon
(
read_ini_uri
(
ps
,
consumer
),
done
,
'<'
)
fsm_transition
(
read_ini_list
(
ps
,
consumer
.
begin_list
()),
done
,
'['
)
fsm_transition
(
read_ini_map
(
ps
,
consumer
.
begin_map
()),
done
,
'{'
)
}
term_state
(
done
)
{
// nop
}
fin
();
// clang-format on
}
/// Reads an INI formatted input.
template
<
class
State
,
class
Consumer
>
void
read_ini_section
(
State
&
ps
,
Consumer
&&
consumer
)
{
using
std
::
swap
;
std
::
string
tmp
;
auto
alnum
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
;
};
auto
alnum_or_dash
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
||
x
==
'-'
;
};
auto
emit_key
=
[
&
]
{
std
::
string
key
;
swap
(
tmp
,
key
);
consumer
.
key
(
std
::
move
(
key
));
};
auto
g
=
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
consumer
.
end_map
();
});
// clang-format off
start
();
// Dispatches to read sections, comments, or key/value pairs.
term_state
(
init
)
{
transition
(
init
,
"
\t\n
"
)
fsm_epsilon
(
read_ini_comment
(
ps
,
consumer
),
init
,
';'
)
transition
(
read_key_name
,
alnum
,
tmp
=
ch
)
}
// Reads a key of a "key=value" line.
state
(
read_key_name
)
{
transition
(
read_key_name
,
alnum_or_dash
,
tmp
+=
ch
)
epsilon
(
await_assignment
)
}
// Reads the assignment operator in a "key=value" line.
state
(
await_assignment
)
{
transition
(
await_assignment
,
"
\t
"
)
transition
(
await_value
,
'='
,
emit_key
())
// The '=' is optional for maps, i.e., `key = {}` == `key {}`.
epsilon
(
await_value
,
'{'
,
emit_key
())
}
// Reads the value in a "key=value" line.
state
(
await_value
)
{
transition
(
await_value
,
"
\t
"
)
fsm_epsilon
(
read_ini_value
(
ps
,
consumer
),
await_eol
)
}
// Waits for end-of-line after reading a value
term_state
(
await_eol
)
{
transition
(
await_eol
,
"
\t
"
)
fsm_epsilon
(
read_ini_comment
(
ps
,
consumer
),
init
,
';'
)
transition
(
init
,
'\n'
)
}
fin
();
// clang-format on
}
/// Reads a nested group, e.g., "[foo.bar]" would consume "[foo.]" in read_ini
/// and then delegate to this function for parsing "bar]".
template
<
class
State
,
class
Consumer
>
void
read_nested_group
(
State
&
ps
,
Consumer
&&
consumer
)
{
using
std
::
swap
;
std
::
string
key
;
auto
alnum
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
;
};
auto
alnum_or_dash
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
||
x
==
'-'
;
};
auto
begin_section
=
[
&
]()
->
decltype
(
consumer
.
begin_map
())
{
consumer
.
key
(
std
::
move
(
key
));
return
consumer
.
begin_map
();
};
auto
g
=
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
consumer
.
end_map
();
});
// clang-format off
start
();
// Scanning for first section.
state
(
init
)
{
epsilon
(
read_sub_section
,
alnum
)
}
// Read the sub section key after reading an '[xxx.'.
state
(
read_sub_section
)
{
transition
(
read_sub_section
,
alnum_or_dash
,
key
+=
ch
)
fsm_transition
(
read_nested_group
(
ps
,
begin_section
()),
done
,
'.'
)
fsm_transition
(
read_ini_section
(
ps
,
begin_section
()),
done
,
']'
)
}
term_state
(
done
)
{
// nop
}
fin
();
// clang-format on
}
/// Reads an INI formatted input.
template
<
class
State
,
class
Consumer
>
void
read_ini
(
State
&
ps
,
Consumer
&&
consumer
)
{
using
std
::
swap
;
std
::
string
tmp
{
"global"
};
auto
alnum
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
;
};
auto
alnum_or_dash
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
||
x
==
'-'
;
};
auto
begin_section
=
[
&
]()
->
decltype
(
consumer
.
begin_map
())
{
std
::
string
key
;
swap
(
tmp
,
key
);
consumer
.
key
(
std
::
move
(
key
));
return
consumer
.
begin_map
();
};
// clang-format off
start
();
// Scanning for first section.
term_state
(
init
)
{
transition
(
init
,
"
\t\n
"
)
fsm_epsilon
(
read_ini_comment
(
ps
,
consumer
),
init
,
';'
)
transition
(
start_section
,
'['
)
fsm_epsilon_if
(
tmp
==
"global"
,
read_ini_section
(
ps
,
begin_section
()),
return_to_global
,
alnum
)
}
// Read the section key after reading an '['.
state
(
start_section
)
{
transition
(
start_section
,
"
\t
"
)
transition
(
read_section_name
,
alnum
,
tmp
=
ch
)
}
// Reads a section name such as "[foo]".
state
(
read_section_name
)
{
transition
(
read_section_name
,
alnum_or_dash
,
tmp
+=
ch
)
fsm_transition
(
read_nested_group
(
ps
,
begin_section
()),
return_to_global
,
'.'
)
epsilon
(
close_section
)
}
// Wait for the closing ']', preceded by any number of whitespaces.
state
(
close_section
)
{
transition
(
close_section
,
"
\t
"
)
fsm_transition
(
read_ini_section
(
ps
,
begin_section
()),
return_to_global
,
']'
)
}
unstable_state
(
return_to_global
)
{
epsilon
(
init
,
any_char
,
tmp
=
"global"
)
}
fin
();
// clang-format on
}
}
// namespace caf::detail::parser
#include "caf/detail/parser/fsm_undef.hpp"
CAF_POP_WARNINGS
libcaf_core/caf/logger.hpp
View file @
a6b6130b
...
...
@@ -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_
;
...
...
libcaf_core/src/actor_system.cpp
View file @
a6b6130b
...
...
@@ -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"
)
...
...
libcaf_core/src/actor_system_config.cpp
View file @
a6b6130b
...
...
@@ -30,7 +30,6 @@
#include "caf/detail/config_consumer.hpp"
#include "caf/detail/gcd.hpp"
#include "caf/detail/parser/read_config.hpp"
#include "caf/detail/parser/read_ini.hpp"
#include "caf/detail/parser/read_string.hpp"
#include "caf/message_builder.hpp"
#include "caf/pec.hpp"
...
...
@@ -50,7 +49,7 @@ actor_system_config::~actor_system_config() {
}
// in this config class, we have (1) hard-coded defaults that are overridden
// by (2)
INI-
file contents that are in turn overridden by (3) CLI arguments
// by (2)
config
file contents that are in turn overridden by (3) CLI arguments
actor_system_config
::
actor_system_config
()
:
cli_helptext_printed
(
false
),
...
...
@@ -61,31 +60,32 @@ actor_system_config::actor_system_config()
stream_desired_batch_complexity
=
defaults
::
stream
::
desired_batch_complexity
;
stream_max_batch_delay
=
defaults
::
stream
::
max_batch_delay
;
stream_credit_round_interval
=
defaults
::
stream
::
credit_round_interval
;
// fill our options vector for creating
INI
and CLI parsers
// fill our options vector for creating
config file
and CLI parsers
using
std
::
string
;
using
string_list
=
std
::
vector
<
string
>
;
opt_group
{
custom_options_
,
"global"
}
.
add
<
bool
>
(
"help,h?"
,
"print help text to STDERR and exit"
)
.
add
<
bool
>
(
"long-help"
,
"print long help text to STDERR and exit"
)
.
add
<
bool
>
(
"dump-config"
,
"print configuration to STDERR and exit"
)
.
add
<
string
>
(
config_file_path
,
"config-file"
,
"set config file (default: caf-application.
ini
)"
);
opt_group
{
custom_options_
,
"stream"
}
"set config file (default: caf-application.
conf
)"
);
opt_group
{
custom_options_
,
"
caf.
stream"
}
.
add
<
timespan
>
(
stream_desired_batch_complexity
,
"desired-batch-complexity"
,
"processing time per batch"
)
.
add
<
timespan
>
(
stream_max_batch_delay
,
"max-batch-delay"
,
"maximum delay for partial batches"
)
.
add
<
timespan
>
(
stream_credit_round_interval
,
"credit-round-interval"
,
"time between emitting credit"
)
.
add
<
st
d
::
st
ring
>
(
"credit-policy"
,
.
add
<
string
>
(
"credit-policy"
,
"selects an algorithm for credit computation"
);
opt_group
{
custom_options_
,
"scheduler"
}
.
add
<
st
d
::
st
ring
>
(
"policy"
,
"'stealing' (default) or 'sharing'"
)
opt_group
{
custom_options_
,
"
caf.
scheduler"
}
.
add
<
string
>
(
"policy"
,
"'stealing' (default) or 'sharing'"
)
.
add
<
size_t
>
(
"max-threads"
,
"maximum number of worker threads"
)
.
add
<
size_t
>
(
"max-throughput"
,
"nr. of messages actors can consume per run"
)
.
add
<
bool
>
(
"enable-profiling"
,
"enables profiler output"
)
.
add
<
timespan
>
(
"profiling-resolution"
,
"data collection rate"
)
.
add
<
string
>
(
"profiling-output-file"
,
"output file for the profiler"
);
opt_group
(
custom_options_
,
"work-stealing"
)
opt_group
(
custom_options_
,
"
caf.
work-stealing"
)
.
add
<
size_t
>
(
"aggressive-poll-attempts"
,
"nr. of aggressive steal attempts"
)
.
add
<
size_t
>
(
"aggressive-steal-interval"
,
"frequency of aggressive steal attempts"
)
...
...
@@ -98,24 +98,23 @@ actor_system_config::actor_system_config()
"frequency of relaxed steal attempts"
)
.
add
<
timespan
>
(
"relaxed-sleep-duration"
,
"sleep duration between relaxed steal attempts"
);
opt_group
{
custom_options_
,
"logger"
}
.
add
<
std
::
string
>
(
"verbosity"
,
"default verbosity for file and console"
)
.
add
<
string
>
(
"file-name"
,
"filesystem path of the log file"
)
.
add
<
string
>
(
"file-format"
,
"line format for individual log file entries"
)
.
add
<
std
::
string
>
(
"file-verbosity"
,
"file output verbosity"
)
.
add
<
std
::
string
>
(
"console"
,
"std::clog output: none, colored, or uncolored"
)
.
add
<
string
>
(
"console-format"
,
"line format for printed log entries"
)
.
add
<
std
::
string
>
(
"console-verbosity"
,
"console output verbosity"
)
.
add
<
std
::
vector
<
std
::
string
>>
(
"component-blacklist"
,
"excluded components for logging"
)
opt_group
{
custom_options_
,
"caf.logger"
}
//
.
add
<
bool
>
(
"inline-output"
,
"disable logger thread (for testing only!)"
);
opt_group
{
custom_options_
,
"middleman"
}
opt_group
{
custom_options_
,
"caf.logger.file"
}
.
add
<
string
>
(
"path"
,
"filesystem path for the log file"
)
.
add
<
string
>
(
"format"
,
"format for individual log file entries"
)
.
add
<
string
>
(
"verbosity"
,
"minimum severity level for file output"
)
.
add
<
string_list
>
(
"excluded-components"
,
"excluded components in files"
);
opt_group
{
custom_options_
,
"caf.logger.console"
}
.
add
<
bool
>
(
"colored"
,
"forces colored or uncolored output"
)
.
add
<
string
>
(
"format"
,
"format for printed console lines"
)
.
add
<
string
>
(
"verbosity"
,
"minimum severity level for console output"
)
.
add
<
string_list
>
(
"excluded-components"
,
"excluded components on console"
);
opt_group
{
custom_options_
,
"caf.middleman"
}
.
add
<
std
::
string
>
(
"network-backend"
,
"either 'default' or 'asio' (if available)"
)
.
add
<
std
::
vector
<
string
>>
(
"app-identifiers"
,
"valid application identifiers of this node"
)
.
add
<
string
>
(
"app-identifier"
,
"DEPRECATED: use app-identifiers instead"
)
.
add
<
bool
>
(
"enable-automatic-connections"
,
"enables automatic connection management"
)
.
add
<
size_t
>
(
"max-consecutive-reads"
,
...
...
@@ -126,7 +125,7 @@ actor_system_config::actor_system_config()
.
add
<
bool
>
(
"manual-multiplexing"
,
"disables background activity of the multiplexer"
)
.
add
<
size_t
>
(
"workers"
,
"number of deserialization workers"
);
opt_group
(
custom_options_
,
"openssl"
)
opt_group
(
custom_options_
,
"
caf.
openssl"
)
.
add
<
string
>
(
openssl_certificate
,
"certificate"
,
"path to the PEM-formatted certificate file"
)
.
add
<
string
>
(
openssl_key
,
"key"
,
...
...
@@ -141,8 +140,9 @@ actor_system_config::actor_system_config()
settings
actor_system_config
::
dump_content
()
const
{
settings
result
=
content
;
auto
&
caf_group
=
result
[
"caf"
].
as_dictionary
();
// -- streaming parameters
auto
&
stream_group
=
result
[
"stream"
].
as_dictionary
();
auto
&
stream_group
=
caf_group
[
"stream"
].
as_dictionary
();
put_missing
(
stream_group
,
"desired-batch-complexity"
,
defaults
::
stream
::
desired_batch_complexity
);
put_missing
(
stream_group
,
"max-batch-delay"
,
...
...
@@ -155,7 +155,7 @@ settings actor_system_config::dump_content() const {
put_missing
(
stream_group
,
"size-policy.bytes-per-batch"
,
defaults
::
stream
::
size_policy
::
bytes_per_batch
);
// -- scheduler parameters
auto
&
scheduler_group
=
result
[
"scheduler"
].
as_dictionary
();
auto
&
scheduler_group
=
caf_group
[
"scheduler"
].
as_dictionary
();
put_missing
(
scheduler_group
,
"policy"
,
defaults
::
scheduler
::
policy
);
put_missing
(
scheduler_group
,
"max-throughput"
,
defaults
::
scheduler
::
max_throughput
);
...
...
@@ -164,7 +164,7 @@ settings actor_system_config::dump_content() const {
defaults
::
scheduler
::
profiling_resolution
);
put_missing
(
scheduler_group
,
"profiling-output-file"
,
std
::
string
{});
// -- work-stealing parameters
auto
&
work_stealing_group
=
result
[
"work-stealing"
].
as_dictionary
();
auto
&
work_stealing_group
=
caf_group
[
"work-stealing"
].
as_dictionary
();
put_missing
(
work_stealing_group
,
"aggressive-poll-attempts"
,
defaults
::
work_stealing
::
aggressive_poll_attempts
);
put_missing
(
work_stealing_group
,
"aggressive-steal-interval"
,
...
...
@@ -180,18 +180,18 @@ settings actor_system_config::dump_content() const {
put_missing
(
work_stealing_group
,
"relaxed-sleep-duration"
,
defaults
::
work_stealing
::
relaxed_sleep_duration
);
// -- logger parameters
auto
&
logger_group
=
result
[
"logger"
].
as_dictionary
();
put_missing
(
logger_group
,
"file-name"
,
defaults
::
logger
::
file_name
);
put_missing
(
logger_group
,
"file-format"
,
defaults
::
logger
::
file_format
);
put_missing
(
logger_group
,
"file-verbosity"
,
defaults
::
logger
::
file_verbosity
);
put_missing
(
logger_group
,
"console"
,
defaults
::
logger
::
console
);
put_missing
(
logger_group
,
"console-format"
,
defaults
::
logger
::
console_format
);
put_missing
(
logger_group
,
"console-verbosity"
,
defaults
::
logger
::
console_verbosity
);
put_missing
(
logger_group
,
"component-blacklist"
,
std
::
vector
<
std
::
string
>
{});
auto
&
logger_group
=
caf_group
[
"logger"
].
as_dictionary
();
put_missing
(
logger_group
,
"inline-output"
,
false
);
auto
&
file_group
=
logger_group
[
"file"
].
as_dictionary
();
put_missing
(
file_group
,
"path"
,
defaults
::
logger
::
file
::
path
);
put_missing
(
file_group
,
"format"
,
defaults
::
logger
::
file
::
format
);
put_missing
(
file_group
,
"excluded-components"
,
std
::
vector
<
std
::
string
>
{});
auto
&
console_group
=
logger_group
[
"console"
].
as_dictionary
();
put_missing
(
console_group
,
"colored"
,
defaults
::
logger
::
console
::
colored
);
put_missing
(
console_group
,
"format"
,
defaults
::
logger
::
console
::
format
);
put_missing
(
console_group
,
"excluded-components"
,
std
::
vector
<
std
::
string
>
{});
// -- middleman parameters
auto
&
middleman_group
=
result
[
"middleman"
].
as_dictionary
();
auto
&
middleman_group
=
caf_group
[
"middleman"
].
as_dictionary
();
auto
default_id
=
to_string
(
defaults
::
middleman
::
app_identifier
);
put_missing
(
middleman_group
,
"app-identifiers"
,
std
::
vector
<
std
::
string
>
{
std
::
move
(
default_id
)});
...
...
@@ -201,7 +201,7 @@ settings actor_system_config::dump_content() const {
put_missing
(
middleman_group
,
"heartbeat-interval"
,
defaults
::
middleman
::
heartbeat_interval
);
// -- openssl parameters
auto
&
openssl_group
=
result
[
"openssl"
].
as_dictionary
();
auto
&
openssl_group
=
caf_group
[
"openssl"
].
as_dictionary
();
put_missing
(
openssl_group
,
"certificate"
,
std
::
string
{});
put_missing
(
openssl_group
,
"key"
,
std
::
string
{});
put_missing
(
openssl_group
,
"passphrase"
,
std
::
string
{});
...
...
@@ -211,31 +211,31 @@ settings actor_system_config::dump_content() const {
}
error
actor_system_config
::
parse
(
int
argc
,
char
**
argv
,
const
char
*
ini
_file_cstr
)
{
const
char
*
config
_file_cstr
)
{
string_list
args
;
if
(
argc
>
1
)
args
.
assign
(
argv
+
1
,
argv
+
argc
);
return
parse
(
std
::
move
(
args
),
ini
_file_cstr
);
return
parse
(
std
::
move
(
args
),
config
_file_cstr
);
}
error
actor_system_config
::
parse
(
int
argc
,
char
**
argv
,
std
::
istream
&
ini
)
{
error
actor_system_config
::
parse
(
int
argc
,
char
**
argv
,
std
::
istream
&
conf
)
{
string_list
args
;
if
(
argc
>
1
)
args
.
assign
(
argv
+
1
,
argv
+
argc
);
return
parse
(
std
::
move
(
args
),
ini
);
return
parse
(
std
::
move
(
args
),
conf
);
}
namespace
{
struct
config_iter
{
std
::
istream
*
ini
;
std
::
istream
*
conf
;
char
ch
;
explicit
config_iter
(
std
::
istream
*
istr
)
:
ini
(
istr
)
{
ini
->
get
(
ch
);
explicit
config_iter
(
std
::
istream
*
istr
)
:
conf
(
istr
)
{
conf
->
get
(
ch
);
}
config_iter
()
:
ini
(
nullptr
),
ch
(
'\0'
)
{
config_iter
()
:
conf
(
nullptr
),
ch
(
'\0'
)
{
// nop
}
...
...
@@ -248,7 +248,7 @@ struct config_iter {
}
inline
config_iter
&
operator
++
()
{
ini
->
get
(
ch
);
conf
->
get
(
ch
);
return
*
this
;
}
};
...
...
@@ -256,7 +256,7 @@ struct config_iter {
struct
config_sentinel
{};
bool
operator
!=
(
config_iter
iter
,
config_sentinel
)
{
return
!
iter
.
ini
->
fail
();
return
!
iter
.
conf
->
fail
();
}
struct
indentation
{
...
...
@@ -335,7 +335,7 @@ error actor_system_config::parse(string_list args, std::istream& config) {
std
::
cout
<<
std
::
flush
;
cli_helptext_printed
=
true
;
}
return
adjust_content
()
;
return
none
;
}
error
actor_system_config
::
parse
(
string_list
args
,
...
...
@@ -348,18 +348,6 @@ error actor_system_config::parse(string_list args,
return
err
;
if
(
config_file_path
==
"$DEFAULT"
)
{
std
::
ifstream
conf
{
"caf-application.conf"
};
// TODO: The .ini parser is deprecated. Remove with CAF 0.19.
if
(
!
conf
.
is_open
())
{
conf
.
open
(
"caf-application.ini"
);
if
(
conf
.
is_open
())
{
// Consume the ini file here, because the parse() overload that takes
// an istream assumes the new config format.
if
(
auto
err
=
parse_ini
(
conf
,
custom_options_
,
content
))
return
err
;
std
::
ifstream
dummy
;
return
parse
(
std
::
move
(
args
),
dummy
);
}
}
return
parse
(
std
::
move
(
args
),
conf
);
}
std
::
ifstream
conf
{
config_file_path
};
...
...
@@ -374,11 +362,6 @@ actor_system_config& actor_system_config::add_actor_factory(std::string name,
actor_system_config
&
actor_system_config
::
set_impl
(
string_view
name
,
config_value
value
)
{
if
(
name
==
"middleman.app-identifier"
)
{
// TODO: Print a warning with 0.18 and remove this code with 0.19.
value
.
convert_to_list
();
return
set_impl
(
"middleman.app-identifiers"
,
std
::
move
(
value
));
}
auto
opt
=
custom_options_
.
qualified_name_lookup
(
name
);
if
(
opt
==
nullptr
)
{
std
::
cerr
<<
"*** failed to set config parameter "
<<
name
...
...
@@ -389,9 +372,10 @@ actor_system_config& actor_system_config::set_impl(string_view name,
}
else
{
opt
->
store
(
value
);
auto
category
=
opt
->
category
();
auto
&
dict
=
category
==
"global"
?
content
:
content
[
category
].
as_dictionary
();
dict
[
opt
->
long_name
()]
=
std
::
move
(
value
);
if
(
category
==
"global"
)
content
[
opt
->
long_name
()]
=
std
::
move
(
value
);
else
put
(
content
,
name
,
std
::
move
(
value
));
}
return
*
this
;
}
...
...
@@ -418,14 +402,6 @@ actor_system_config::parse_config_file(const char* filename,
std
::
ifstream
f
{
filename
};
if
(
!
f
.
is_open
())
return
make_error
(
sec
::
cannot_open_file
,
filename
);
// TODO: The .ini parser is deprecated. Remove this block with CAF 0.19.
string_view
fname
{
filename
,
strlen
(
filename
)};
if
(
ends_with
(
fname
,
".ini"
))
{
settings
result
;
if
(
auto
err
=
parse_ini
(
f
,
opts
,
result
))
return
err
;
return
result
;
}
return
parse_config
(
f
,
opts
);
}
...
...
@@ -456,19 +432,6 @@ error actor_system_config::parse_config(std::istream& source,
return
none
;
}
error
actor_system_config
::
parse_ini
(
std
::
istream
&
source
,
const
config_option_set
&
opts
,
settings
&
result
)
{
if
(
!
source
)
return
make_error
(
sec
::
runtime_error
,
"source stream invalid"
);
detail
::
config_consumer
consumer
{
opts
,
result
};
parser_state
<
config_iter
,
config_sentinel
>
res
{
config_iter
{
&
source
}};
detail
::
parser
::
read_ini
(
res
,
consumer
);
if
(
res
.
i
!=
res
.
e
)
return
make_error
(
res
.
code
,
res
.
line
,
res
.
column
);
return
none
;
}
error
actor_system_config
::
extract_config_file_path
(
string_list
&
args
)
{
auto
ptr
=
custom_options_
.
qualified_name_lookup
(
"global.config-file"
);
CAF_ASSERT
(
ptr
!=
nullptr
);
...
...
@@ -489,25 +452,6 @@ error actor_system_config::extract_config_file_path(string_list& args) {
return
none
;
}
error
actor_system_config
::
adjust_content
()
{
// TODO: Print a warning to STDERR if 'app-identifier' is present with 0.18
// and remove this code with 0.19.
auto
i
=
content
.
find
(
"middleman"
);
if
(
i
!=
content
.
end
())
{
if
(
auto
mm
=
get_if
<
settings
>
(
&
i
->
second
))
{
auto
j
=
mm
->
find
(
"app-identifier"
);
if
(
j
!=
mm
->
end
())
{
if
(
!
mm
->
contains
(
"app-identifiers"
))
{
j
->
second
.
convert_to_list
();
mm
->
emplace
(
"app-identifiers"
,
std
::
move
(
j
->
second
));
}
mm
->
container
().
erase
(
j
);
}
}
}
return
none
;
}
const
settings
&
content
(
const
actor_system_config
&
cfg
)
{
return
cfg
.
content
;
}
...
...
libcaf_core/src/config_option_set.cpp
View file @
a6b6130b
...
...
@@ -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
;
...
...
libcaf_core/src/detail/ini_consumer.cpp
deleted
100644 → 0
View file @
13b5d670
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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
libcaf_core/src/group_manager.cpp
View file @
a6b6130b
...
...
@@ -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
);
}
...
...
libcaf_core/src/inbound_path.cpp
View file @
a6b6130b
...
...
@@ -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"
)
...
...
libcaf_core/src/logger.cpp
View file @
a6b6130b
...
...
@@ -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
)
...
...
libcaf_core/src/scheduler/abstract_coordinator.cpp
View file @
a6b6130b
...
...
@@ -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
();
...
...
libcaf_core/test/actor_lifetime.cpp
View file @
a6b6130b
...
...
@@ -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"
);
}
};
...
...
libcaf_core/test/detail/ini_consumer.cpp
deleted
100644 → 0
View file @
13b5d670
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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
()
libcaf_core/test/detail/parser/read_ini.cpp
deleted
100644 → 0
View file @
13b5d670
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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
()
libcaf_core/test/logger.cpp
View file @
a6b6130b
...
...
@@ -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
)
{
...
...
libcaf_core/test/native_streaming_classes.cpp
View file @
a6b6130b
...
...
@@ -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
;
}
...
...
libcaf_core/test/thread_hook.cpp
View file @
a6b6130b
...
...
@@ -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
())
...
...
libcaf_io/src/io/basp/instance.cpp
View file @
a6b6130b
...
...
@@ -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
));
...
...
libcaf_io/src/io/basp_broker.cpp
View file @
a6b6130b
...
...
@@ -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
);
...
...
libcaf_io/src/io/middleman.cpp
View file @
a6b6130b
...
...
@@ -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
{
...
...
libcaf_io/src/io/middleman_actor.cpp
View file @
a6b6130b
...
...
@@ -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
));
}
...
...
libcaf_io/src/io/network/datagram_handler.cpp
View file @
a6b6130b
...
...
@@ -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
),
...
...
libcaf_io/src/io/network/default_multiplexer.cpp
View file @
a6b6130b
...
...
@@ -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
)
{
...
...
libcaf_io/src/io/network/stream.cpp
View file @
a6b6130b
...
...
@@ -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
),
...
...
libcaf_io/test/io/basp_broker.cpp
View file @
a6b6130b
...
...
@@ -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
());
...
...
libcaf_openssl/src/openssl/manager.cpp
View file @
a6b6130b
...
...
@@ -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
;
}
...
...
libcaf_openssl/src/openssl/middleman_actor.cpp
View file @
a6b6130b
...
...
@@ -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
));
}
...
...
libcaf_openssl/test/openssl/authentication.cpp
View file @
a6b6130b
...
...
@@ -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
()
{
...
...
libcaf_openssl/test/openssl/remote_actor.cpp
View file @
a6b6130b
...
...
@@ -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
);
}
};
...
...
libcaf_test/caf/test/dsl.hpp
View file @
a6b6130b
...
...
@@ -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
;
}
...
...
manual/ConfiguringActorApplications.rst
View file @
a6b6130b
...
...
@@ -124,8 +124,8 @@ object *before* initializing an actor system with it.
.. _system-config-options:
Command Line Options and Configuration File
s
---------------
-----------------------------
Program Option
s
---------------
CAF organizes program options in categories and parses CLI arguments as well as
configuration files. CLI arguments override values in the configuration file
...
...
@@ -137,13 +137,13 @@ adds three options to the ``global`` category.
:language: C++
:lines: 206-218
We create a new ``global`` category in ``custom_options_``.
Each following call to ``add`` then appends individual options to the
category. The first argument to ``add`` is the associated variable. T
he
second argument is the name for the parameter, optionally suffixed with a
comma-separated single-character short name. The short name is only considered
for CLI parsing and allows users to abbreviate commonly used option names. The
third and final argument to ``add``
is a help text.
We create a new ``global`` category in ``custom_options_``.
Each following call
to ``add`` then appends individual options to the category. The first argument
to ``add`` is the associated variable. The second argument is the name for t
he
parameter, optionally suffixed with a comma-separated single-character short
name. The short name is only considered for CLI parsing and allows users to
abbreviate commonly used option names. The third and final argument to ``add``
is a help text.
The custom ``config`` class allows end users to set the port for the application
to 42 with either ``-p 42`` (short name) or ``--port=42`` (long name). The long
...
...
@@ -152,27 +152,28 @@ option name is prefixed by the category when using a different category than
end users have to type ``--foo.port=42`` when using the long name. Short names
are unaffected by the category, but have to be unique.
Boolean options do not require arguments. The member variable
``server_mode`` is set to ``true`` if the command line contains
either ``--server-mode`` or ``-s``.
Boolean options do not require arguments. The member variable ``server_mode`` is
set to ``true`` if the command line contains either ``--server-mode`` or ``-s``.
The example uses member variables for capturing user-provided settings for
simplicity. However, this is not required. For example,
``add<bool>(...)`` allows omitting the first argument entirely. All
values of the configuration are accessible with ``get_or``. Note that
all global options can omit the ``"global."`` prefix.
simplicity. However, this is not required. For example, ``add<bool>(...)``
allows omitting the first argument entirely. All values of the configuration are
accessible with ``get_or``. Note that all global options can omit the
``"global."`` prefix.
CAF adds the program options ``help`` (with short names ``-h`` and ``-?``) as
well as ``long-help`` to the ``global`` category.
CAF adds the program options ``help`` (with short names ``-h``
and ``-?``) as well as ``long-help`` to the ``global``
category.
Configuration Files
-------------------
The default name for the configuration file is ``caf-application.conf``. Users
can change the file
name and path by passing ``--config-file=<path>`` on the
command
line.
can change the file
path by passing ``--config-file=<path>`` on the command
line.
The syntax for the configuration files provides a clean JSON-like grammar that
is similar to
commonly used configuration formats such as the file format of
``lighttpd``. In a nutshell, instead
of writing:
is similar to
other commonly used configuration formats. In a nutshell, instead
of writing:
.. code-block:: JSON
...
...
@@ -341,31 +342,33 @@ system-config-options_ are silently ignored if logging is disabled.
.. _log-output-file-name:
File Name
~~~~~~~~~
File
~~~~
File output is disabled per default. Setting ``caf.logger.file.verbosity`` to a
valid severity level causes CAF to print log events to the file specified in
``caf.logger.file.path``.
The
output file is generated from the template configured by
``logger-file-name``. This template supports the following variables.
The
``caf.logger.file.path`` may contain one or more of the following
placeholders:
+----------------+--------------------------------+
+----------------
-
+--------------------------------+
| **Variable** | **Output** |
+----------------+--------------------------------+
+----------------
-
+--------------------------------+
| ``[PID]`` | The OS-specific process ID. |
+----------------+--------------------------------+
| ``[TIMESTAMP]``| The UNIX timestamp on startup. |
+----------------+--------------------------------+
+----------------
-
+--------------------------------+
| ``[TIMESTAMP]``
| The UNIX timestamp on startup. |
+----------------
-
+--------------------------------+
| ``[NODE]`` | The node ID of the CAF system. |
+----------------+--------------------------------+
+----------------
-
+--------------------------------+
.. _log-output-console:
Console
~~~~~~~
Console output is disabled per default. Setting ``logger-console`` to
either ``"uncolored"`` or ``"colored"`` prints log events to
``std::clog``. Using the ``"colored"`` option will print the
log events in different colors depending on the severity level.
Console output is disabled per default. Setting ``caf.logger.console.verbosity``
to a valid severity level causes CAF to print log events to ``std::clog``.
.. _log-output-format-strings:
...
...
@@ -373,47 +376,46 @@ Format Strings
~~~~~~~~~~~~~~
CAF uses log4j-like format strings for configuring printing of individual
events via ``
logger-file-
format`` and
``
logger-console-
format``. Note that format modifiers are not supported
events via ``
caf.logger.file.
format`` and
``
caf.logger.console.
format``. Note that format modifiers are not supported
at the moment. The recognized field identifiers are:
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
| **Character**| **Output** |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| **Character**
| **Output** |
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``c`` | The category/component. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``C`` | The full qualifier of the current function. For example, the qualifier of ``void ns::foo::bar()`` is printed as ``ns.foo``. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``d`` | The date in ISO 8601 format, i.e., ``"YYYY-MM-DDThh:mm:ss"``. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``F`` | The file name. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``L`` | The line number. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``m`` | The user-defined log message. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``M`` | The name of the current function. For example, the name of ``void ns::foo::bar()`` is printed as ``bar``. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``n`` | A newline. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``p`` | The priority (severity level). |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``r`` | Elapsed time since starting the application in milliseconds. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``t`` | ID of the current thread. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``a`` | ID of the current actor (or ``actor0`` when not logging inside an actor). |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
| ``%`` | A single percent sign. |
+--------------+-----------------------------------------------------------------------------------------------------------------------------+
+--------------
-
+-----------------------------------------------------------------------------------------------------------------------------+
.. _log-output-filtering:
Filtering
~~~~~~~~~
The two configuration options ``logger.component-blacklist`` and
``logger.(file|console)-verbosity`` reduce the amount of generated log events.
The former is a list of excluded component names and the latter can increase the
reported severity level (but not decrease it beyond the level defined at compile
time).
The two configuration options ``caf.logger.file.excluded-components`` and
``caf.logger.console.excluded-components`` reduce the amount of generated log
events in addition to the minimum severity level. These parameters are lists of
component names that shall be excluded from any output.
tools/caf-run.cpp
View file @
a6b6130b
...
...
@@ -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
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment