All notable changes to this project will be documented in this file. The format is based on Keep a Changelog.
- CAF now requires C++20 to build.
- When using the HTTP client API, SSL hostname validation is now enabled by
default. Users can disable it by setting
hostname_validationtofalseif necessary. This change was made to improve security by default. - Serializer interfaces have received an overhaul to allow custom serialization
of actor handles. There are also two new base types for serialization:
byte_readerandbyte_writer. These new types allow users to write generic code for serializers that operate on byte sequences. - The metric
caf.system.running-actorsnow has a label dimensionnamethat allows users to identify which kinds of actors are currently active. Since tracking this metric has become slightly more expensive due to the new label, collecting it can now be disabled via the configuration optioncaf.metrics.disable-running-actors. - The configuration options under
caf.metrics-filtershave been moved tocaf.metrics.filters. This change was made to make the configuration options more consistent. - The default maximum message size for the length-prefix framing has been reduced to 64 MB. This change was made to improve security by default.
- Creating a response promise no longer invalidates
self->current_sender(). - Improved compile-time error messages when passing ill-formed message handler signatures to typed actors.
- The CMake variable
CAF_LOG_LEVELhas been removed. At run-time, users can enable logging up to thedebuglog level by default. Setting a higher log level than that will have no effect since trace logging remains disabled by default and must be enabled manually by setting the CMake optionCAF_ENABLE_TRACE_LOGGINGtoON. When using theconfigurescript, this can be achieved by passing the new--enable-trace-loggingoption to the script. - The classes
schedulerandresumablehave received a complete overhaul to better hide implementation details and to improve maintainability. - The
is_sumparameter for counters now defaults totrueinstead offalse. In the Prometheus output, this means that name for the counter will be suffixed with_total, which is the standard suffix for counters. - The method
caf::actor_registry::runningmoved tocaf::actor_system::running_actors_count. Other methods for manipulating the count have been removed and replaced by private methods on theactor_systemsince they are meant for internal use only. - Outstanding
http::requestobjects now keep their connection "alive" for the purpose ofmax_connectionstracking. Previously, only open sockets counted against the limit, which could cause the server to accept new connections while there were still pending requests being processed. - Metrics actor name filters (
caf.metrics.filters.includeandcaf.metrics.filters.exclude) now use simple wildcard matching with*(zero or more characters) and?(exactly one character) only. Glob-style patterns (**,/,\) are no longer supported. - Messages that CAF sends as part of terminating an actor such as
exit_msganddown_msgare now always sent anonymously, i.e., without a sender. This avoids adding strong references to actors that are already shutting down. For actors that terminate because they became unreachable, this change allows CAF to destroy the actor object immediately after running cleanup code instead of having to wait for the newly added references to expire again. - The
attachable::actor_exitedmember function has received an additionalabstract_actor* selfparameter. This allows us to remove weak pointers in the attachable implementations to avoid unnecessary increment and decrement operations on the reference count.
- The type
caf::spanand the utility functionmake_spanare now deprecated and will be removed in the next major release. Now that CAF updated its minimum required C++ standard to C++20, we have switched to usingstd::spanthroughout the code base and users should do the same. - The alias
caf::net::lp::frameis now deprecated and will be removed in the next major release. Users should usecaf::chunkdirectly instead. - All legacy macros for logging have been deprecated:
CAF_LOG_DEBUG,CAF_LOG_DEBUG_IF,CAF_LOG_INFO,CAF_LOG_INFO_IF,CAF_LOG_WARNING,CAF_LOG_WARNING_IF,CAF_LOG_ERROR, andCAF_LOG_ERROR_IF. Users should use the new logging API instead. - The member functions
anon_send,scheduled_anon_send, anddelayed_anon_sendof the classlocal_actorare now deprecated in favor of using the freeanon_mailfunction instead. - The members
operator boolandoperator!oncaf::errorare now deprecated. Allowing boolean conversions from this type makes it too easy to misinterpret the meaning of anifstatement and thus leads to subtle bugs. Please use.empty()and.valid()instead to determine whether an error has been default-constructed or holds a valid error code. - The methods
or_elseandevaloncaf::errorare now deprecated since they overlap with methods such astransformandand_thenoncaf::expected. - The constructors and assignment operators of
caf::intrusive_ptrandcaf::weak_intrusive_ptrthat accept a boolean flag to control whether the reference count should be increased or not have been deprecated. Users should use the newadd_refandadopt_reftags instead. - Deprecate all member functions in
caf::expectedthat are not present instd::expected. - The enumerator
spawn_options::priority_aware_flagis a relict of pre-0.18 versions of CAF and had no effect for a long time. It is now deprecated and will be removed in the next major release. - The
operator booloncaf::error_codeis now deprecated. Use.empty()or.valid()instead to determine whether an error code was default-constructed or holds a non-zero value (#2211). - The method
actor_system::redirect_text_outputis now deprecated. Configure a console printer instead viaactor_system_config::console_printer_factory()before constructing the actor system.
- CAF's intrusive pointer API now uses explicit
add_refandadopt_reftags to control whether the reference count should be increased or not instead of relying on boolean flags. - Added
monitorAPI to WebSocket and HTTP servers in thewithDSL (#2026). - When starting a server or client using length-prefix framing, users can now
specify the maximum message size via
max_message_sizeand the number of bytes for the length prefix viasize_field. - The namespace
caf::net::httpnow contains two new classes for dealing with HTTP multipart requests and responses:multipart_readerandmultipart_writer. - Users can now set a global default handler for exceptions on the
actor_system_configby callingexception_handler(my_handler). This handler then gets passed down to all scheduled actors as the default exception handler but can still be overridden by actors. - The HTTP server implementation now accepts chunked transfer encoding for incoming requests (#2205).
- Users can now define
CAF_SUPPRESS_DEPRECATION_WARNINGSto silence all deprecation warnings emitted by CAF headers. By turning deprecation warnings off, users can migrate their code base in multiple steps without getting less urgent warnings. Of course, we recommend using this macro only for a short transition period since deprecated APIs will usually be removed in the next major release. - The new static method
caf::abstract_actor::current()grants users access to the actor currently associated with the calling thread (returnsnullptrif no actor is associated with the thread). - To make
caf::expecteda drop-in replacement forstd::expected, we have added missing utility types such ascaf::unexpectandcaf::unexpected. Further, users can optionally build CAF withCAF_USE_STD_EXPECTEDenabled to have CAF use aliases to the standard library types instead of its own implementation (requires C++23). - The class
http::requestnow has anorphaned()method that returnstrueif the underlying connection has been shut down. This allows request handlers to safely discard abandoned requests. - The new configuration option
caf.clock.cleanup-intervalenables periodic cleanup of disposed jobs from the actor clock. By setting this option, users can reduce the memory usage of the actor clock when the application frequently schedules actions with long delays that usually get disposed before they run. - Users can now set the new config parameter
caf.logger.console.streamtosystemto have the console logger useactor_system::printlninstead of writing tostderr. This avoids mangled output on the console when enabling console logging while also printing from actors. - Setting the new CMake option
CAF_ENABLE_RTTItoOFFwill now disable all uses oftypeidanddynamic_castin CAF. This enables users to build CAF with compiler options such as-fno-rtti.
- Errors that arise during the
withDSL setup of servers and clients now properly callon_error(#2026). - Fix UBSan finding regarding non-aligned memory allocation when spawning actors.
- Fix build issues on some BSD derivatives (#2135).
- Fix alignment of
caf::async::batchon 32bit ARM architecture (#2142). - Timestamps in log output are now rendered without surrounding quotes (#2216).
- Actors now keep track of any other actor they have monitored during their lifetime. When terminating, actors will now remove themselves from the monitoring lists of other actors to avoid leaving stale weak pointers behind. This change allows CAF to clean up memory earlier. In extreme cases, like having central actors that are frequently monitored but usually live for the duration of the application, those stale weak pointers effectively caused memory leaks since memory can only be freed fully once all strong and weak references have expired.
- Fix a heap-buffer-overflow in the test runner on missing CLI arguments. For
example, running
caf-core-test -spreviously crashed (-srequires an argument, #2384).
- For event-based actors (
scheduled_actor), removedset_down_handlerand the single-argumentmonitor/demonitoroverloads for actor handles. Usemonitor(handle, callback)and the returneddisposableinstead (#1873). - Removed the with DSL building base classes form
caf/net/dsl/(#2026). - Removed the deprecated
actor_ostreamclass and theaoututility. They have been deprecated since CAF 1.0.0. Users should now useprintlninstead, which is available on actors as well as on theactor_system. - The getters
spawn_servandconfig_servhave been removed from the public interface ofactor_system. These actors are an implementation detail of the I/O module and should not be accessed directly by users. - The method
logger::thread_local_aid(actor_id)as well as the macrosCAF_PUSH_AID,CAF_PUSH_AID_FROM_PTRandCAF_SET_AIDhave been removed. They were technically part of the public API but were never intended to be called by users. - Removed the implicit conversions from
caf::error_codetocaf::errorand from error code enums tocaf::error_code. - The template class
intrusive_ptr_accesshas been removed without replacement. Users could always provideintrusive_ptr_add_refandintrusive_ptr_releaseas customization point. Providing two customization points for the same functionality only adds redundancy. - Removed the
node_id::can_parsemethod and theparsefunction for node IDs. Both are leftovers from older versions of CAF and no longer serve any purpose.
1.1.0 - 2025-07-25
- Add intermediary types for the
mailAPI as[[nodiscard]]to make it easier to spot mistakes when chaining calls. - The
mergeandflat_mapoperators now accept an optional unsigned integer parameter to configure the maximum number of concurrent subscriptions. - If an actor terminates, it will now consistently send error messages with code
caf::sec::request_receiver_downto all outstanding requests. Any request that arrives after an actor has closed its mailbox will receive the same error code. This change makes it easier to handle errors in a consistent way and to distinguish between requests that have been dropped and those that resulted in an error while processing the request (#2070). - The URI parser in CAF now accepts URIs that use reserved characters such as
*,/or?in the query string. This change follows the recommendation in the RFC 3986, which states that "query components are often used to carry identifying information in the form of key=value pairs and one frequently used value is a reference to another URI". - CAF now respects CPU limits when running in a container to determine the thread pool size for the scheduler (#2061).
- New flow operators:
retry,combine_latest,debounce,throttle_firstandon_error_resume_next. - New
with_userinfomember function for URIs that allows setting the user-info sub-component without going through an URI builder. - CAF now supports chunked encoding for HTTP clients (#2038).
- Added a missing configuration option to the HTTP client API that allows users to set the maximum size of the response.
- Add functions to the SSL API to enable Server Name Indication (SNI, #2084).
- Add
throttle_lastto observables: an alias forsample.
- Fix build error in
caf-netwhen building with C++23 (#1919). - Restructure some implementation details of
intrsuive_ptr(no functional changes) to make it easier forclang-tidyto analyze the code. This fixes a false positive reported byclang-tidyin some use cases whereclang-tidywould falsely report a use-after-free bug. - Closing a WebSocket connection now properly sends a close frame to the client before closing the TCP connection (#1938).
- Fix a build error in the unit tests when building with C++20 and setting
CAF_USE_STD_FORMATtoON(#1963). - The functions
run_scheduled,run_scheduled_weak,run_delayedandrun_delayed_weaknow properly accept move-only callback types. - Fix the conversion from invalid actor handles to raw pointers when using
actor_cast. This resolves an issue withsendthat could lead to undefined behavior (#1972). - Add missing export declaration for the
caf::net::prometheussymbol (#2042). - Boolean flags now accept arguments on the command line (#2048). For example,
--foo=trueis now equivalent to--fooand--foo=falsewill set the flag tofalse. Short options like-fonly accept the argument when passing it without a space, e.g.,-ffalse. - The
bufferandintervaloperators now properly check the time period parameter and produce an error if the period is zero or negative (#2030). Passing an invalid delay parameter toto_streamorto_typed_streamlikewise produces a stream that immediately callson_erroron any client that tries to subscribe to it. - Use
localtime_son all Windows platforms to fix a build error with MSYS/UCRT64 (#2059). - Fix rendering of nested JSON lists (#2068).
- Add missing
pragma onceguards to multiple headers undercaf/net/ssl/. - Fix the behavior of
use_certificate_file_ifanduse_private_key_file_if. Both functions did not leave thecaf::net::ssl::contextunchanged if one of the arguments was invalid but instead applied the invalid arguments to the context regardless, resulting in an OpenSSL error. - Fix a bug in the HTTP parser that could cause the parser to try parsing the payload as a new request.
- Fix a startup issue when configuring Prometheus export on
caf.net(#2060). This bug caused the Prometheus server to never start up unless starting at least one other asynchronous server or client using thecaf.netAPI. - Fix a bug in the URI parser that could crash the application when parsing an URI with a percent-encoded character at the end of the string (#2080).
- Fix parsing of HTTP request headers that do not use the absolute path syntax in the first line (#2074).
- Optimize templates for compile-time checks used by typed behaviors. This drastically reduces memory usage during compilation and avoids OOM errors when spawning typed actors with a large number of message handlers (#1970).
- BDD outlines now properly handle multiple
WHENblocks in a single scenario (#1776). - Fix build issues on Clang 20 when building in C++20 mode (#2092).
1.0.2 - 2024-10-30
- Tests, scenarios and outlines are now automatically put into the anonymous namespace to avoid name clashes with other tests. This removes the need for users to manually put their tests into an anonymous namespace.
- The
SUITEmacro of the unit test framework can now be used multiple times in a single compilation unit.
- When using the HTTP client API, the client now properly closes the connection after receiving a response even if the server would keep the connection open.
- When using the WebSocket client API, the socket could close prematurely when
leaving
mainright after setting up the connection, even when starting an actor instart. This was due to CAF not holding onto a strong reference to the connection object (and thus the actor) at all times (#1918). - When using log statements in unit tests, e.g.
log::test::debug, the output will now be rendered by default even when not using the deterministic fixture. - Registering a custom option of type
size_twill no longer print<dictionary>as type hint in the--helpoutput. Instead, CAF will print eitheruint32_toruint64_t, depending on the platform. - Fix handling of unicode escaping (e.g.
\u00E4) in the JSON parser (#1937).
1.0.1 - 2024-07-23
- Fix a compiler error when using
spawn_clienton the I/O middleman (#1900). - An unfortunate bug prevented the auto-detection of
std::formatwhen building CAF with C++20 or later. This bug has been fixed, alongside issues with the actualstd::format-based implementation. However, since selecting a different backend forprintlnand the log output generation breaks the ABI, we have decided to ship thestd::format-based implementation only as opt-in at this point. Users can enable it by setting the CMake optionCAF_USE_STD_FORMAT. - Fix cleanup in the consumer adapter. This component connects actors to SPSC buffers. If the SPSC buffer was closed by the producer, the consumer adapter failed to properly dispose pending actions.
- Fix a
nullptr-dereference inscheduled_actor::run_actionsif a delayed action callsself->quit()(#1920).
- When disposing a connection acceptor, CAF no longer generates a log event with
severity
error. Instead, it will log the event with severitydebug. - The
http::routermember functionshutdownhas been deprecated and renamed toabort_and_shutdownto better reflect its functionality.
1.0.0 - 2024-06-26
- The actor system now offers a
printlnconvenience function for printing to the console. When building CAF with C++20 enabled, the function usesstd::formatinternally. Otherwise, it falls back to the compatibility layer with the same syntax. The function also recognizesinspectoverloads for custom types. Any printing done by this function is thread-safe. The function is available on actors in order to allowself->println("..."). - Actors have a new
monitormember function that takes an actor handle and a callback. The callback will run when the monitored actor terminates (in the context of the monitoring actor). The function returns amonitorableobject that can be used to cancel the monitoring. This mechanism replaces the old approach that relied ondown_msghandlers in event-based actors (nothing changes for blocking actors). - Event-based actors can now set an idle timeout via
set_idle_handler. The timeout fires when the actor receives no messages for a specified duration. This new feature replaces theafter(...) >> ...syntax and allows actors to specify what kind of reference CAF will hold to that actor while it is waiting for the timeout (strong or weak) and whether to trigger the timeout once or repeatedly. - New flow operators:
buffer,sample,start_with,on_backpressure_buffer,on_error_return,on_error_return_item, andon_error_complete. - The unit test framework now offers the new utility (template) class
caf::test::approxfor approximate comparisons.
- Fix building CAF with shared libraries (DLLs) enabled on Windows (#1715).
- The
actor_from_stateutility now evaluates spawn options such aslinked(#1771). Previously, passing this option toactor_from_stateresulted in a compiler error. - Sending a message to an already terminated actor from a
function_viewnow properly reports an error (#1801). - URIs now support support username and password in the user-info sub-component
(#1814). Consequently, the
userinfofield of the URI class now has two member variables:nameand (an optional)password. Further, theuserinfofield is now optional in order to differentiate between an empty user-info and no user-info at all. - The parser for reading JSON and configuration files now properly handles Windows-style line endings (#1850).
- Calling
force_utcon acaf::chrono::datetimeobject now properly applies the UTC offset. Previously, the function would shift the time into the wrong direction (#1860). - Fix a regression in the work-stealing scheduler that prevented workers from stealing work from other workers in the relaxed polling state (#1866).
- Fix handling of integer or boolean values as keys as well as lists as values
in dictionaries when using the
json_builder. - Calling
caf::chrono::datetime::to_local_timewill now properly interpret the stored time as local time if no UTC offset is present.
- The obsolete CAF types
caf::string_view,caf::byte,caf::optional,caf::replies_to, andcaf::flow::item_publisher. - The obsolete
operator*for "combining" two actor handles. - All
to_streamandto_typed_streammember functions on actors (they are available oncaf::flow::observabledirectly). - The
groupAPI has been removed entirely. - The experimental APIs for actor profiling and inserting tracing data have been removed. Neither API has a clear use case at the moment and since we have not received any feedback on either API, we have decided to remove them to simplify the code base.
- The
actor_system_configno longer contains special member variables for the OpenSSL module. The module now uses the regular configuration system. - The
caf-runtool no longer ships with CAF. The tool has not been maintained for a long time, has never been thoroughly tested, and has no documentation. - The
actor_system_configno longer contains thelogger_factorysetter. We might reintroduce this feature in the future, but we think the newloggerinterface class is not yet stable enough to expose it to users and to allow custom logger implementations.
- When using the caf-net module, users may enable Prometheus metric export by
setting the configuration option
caf.net.prometheus-http. The option has the following fields:port,address,tls.key-file, andtls.cert-file. When setting the TLS options, the server will use HTTPS instead of HTTP. - Sending messages from cleanup code (e.g., the destructor of a state class) is now safe. Previously, doing so could cause undefined behavior by forming a strong reference to a destroyed actor.
- Actors will now always send an error message if an incoming message triggered an unhandled exception. Previously, CAF would only send an error message if the incoming message was a request (#1684).
- Stateful actors now provide a getter function
state()instead of declaring a publicstatemember variable. This change enables more flexibility in the implementation for future CAF versions. - Passing a class to
spawn_inactiveis now optional and defaults toevent_based_actor. The next major release will remove the class parameter altogether. - Event-based actors can now handle types like
exit_msganderrorin their regular behavior. - The
check_eqandrequire_eqfunctions in the unit test framework now prohibit comparing floating-point numbers with==. Instead, users should use newapproxutility class. - The member functions
send,scheduled_send,delayed_send,requestanddelegateare deprecated in favor of the newmailAPI. - The free functions
anon_send,delayed_anon_send,scheduled_anon_sendare deprecated in favor of the newanon_mailAPI.
- Using
spawn_inactivenow emits a deprecation warning when passing a class other thanevent_based_actor. - The experimental
actor_poolAPI has been deprecated. The API has not seen much use and is too cumbersome. - The printing interface via
aouthas been replaced by the newprintlnfunction. The old interface is now deprecated and will be removed in the next major release. - Calling
monitorwith a single argument is now deprecated for event-based actors. Users should always provide a callback as the second argument. Note that nothing changes for blocking actors. They still callmonitorand then receive adown_msgin their mailbox. - The function
set_down_handleris deprecated for the same reasons asmonitor: please use the newmonitorAPI with a callback instead. - The spawn flag
monitoredis deprecated as well and users should callmonitordirectly instead. - Constructing a behavior with
after(...) >> ...has been deprecated in favor of the newset_idle_handlerfunction. Note that blocking actors may still pass a timeout viaafter(...)toreceivefunctions. The deprecation only targets event-based actors. - The use case for
function_viewis covered by the new feature on blocking actors that allows callingreceivewith no arguments. Hence,function_viewbecomes obsolete and is deprecated. - The
set_default_handlermember function on event-based actors is now deprecated. Instead, users should use a handler formessagein their behavior as a catch-all. For skipping messages, CAF now includes a newmail_cacheclass that allows explicitly stashing messages for later processing. - Special-purpose handlers for messages like
exit_msganderrorare now deprecated. Instead, users should handle these messages in their regular behavior. - The legacy testing framework in
caf/test/unit_test.hppis now deprecated and the header (as well as headers that build on top it such ascaf/test/dsl.hpp) will be removed in the next major release. Users should migrate to the new testing framework.
0.19.5 - 2024-01-08
- An
observablethat runs on an actor can now be converted to astreamortyped_streamdirectly by callingto_streamorto_typed_streamon it. - New
caf::asyncAPI to read text and binary files asynchronously in a separate thread. The contents of the files are consumed as flows (#1573). - The class
caf::unordered_flat_mapnow has thecontainsandinsert_or_assignmember functions. - CAF now supports setting custom configuration options via environment
variables. The new priority order is: CLI arguments, environment variables,
configuration files, and default values. The environment variable name is
the full name of the option in uppercase, with all non-alphanumeric
characters replaced by underscores. For example, the environment variable
FOO_BARsets the optionfoo.bar. Users may also override the default name by putting the environment name after the short names, separated by a comma. For example,opt_group{custom_options_, "foo"}.add("bar,b,MY_BAR")overrides the default environment variable nameFOO_BARwithMY_BAR. - The formatting functions from
caf/chrono.hppnow support precision for the fractional part of the seconds and an option to print with a fixed number of digits. - The new class
caf::chunkrepresents an immutable sequence of bytes with a fixed size. Unlikestd::span, achunkowns its data and can be (cheaply) copied and moved. - Users can now convert state classes with a
make_behaviormember function into a "function-based actor" via the newactor_from_stateutility. For example,sys.spawn(caf::actor_from_state<my_state>, args...)creates a new actor that initializes its state withmy_state{args...}and then callsmake_behavior()on the state object to obtain the initial behavior. - The
aoututility received aprintlnmember function that adds a formatted line to the output stream. The function uses the same formatting backend as the logging API.
- The class
caf::test::outlineis now properly exported from the test module. This fixes builds with dynamic linking againstlibcaf_test. - Fix a crash with the new deterministic test fixture when cleaning up actors with stashed messages (#1589).
- When using
request(...).await(...), the actor no longer suspends handling of system messages while waiting for the response (#1584). - Fix compiler errors and warnings for GCC 13 in C++23 mode (#1583).
- Fix encoding of chunk size in chunked HTTP responses (#1587).
- Fix leak when using
spawn_inactiveand not launching the actor explicitly (#1597). - Fix a minor bug in the deserialization of messages that caused CAF to allocate more storage than necessary (#1614).
- Add missing
consttopublisher<T>::observe_on. - All
observableimplementations now properly callon_subscribeon their subscriber before callingon_error. - The function
config_value::parsenow properly handles leading and trailing whitespaces. - Comparing two
caf::unordered_flat_mappreviously relied on the order of elements in the map and thus could result in false negatives. The new implementation is correct and no longer relies on the order of elements. - When using
--dump-config, CAF now properly renders nested dictionaries. Previously, dictionaries in lists missed surrounding braces. - CAF now parses
foo.bar = 42in a config file asfoo { bar = 42 }, just as it does for CLI arguments. - Fix shutdown logic for actors with open streams. This resolves an issue where actors would not terminate correctly after receiving an exit message (#1657).
- Fix compilation error on MSVC when building
caf_testwith shared libraries enabled (#1669). - Calling
delay_for_fnon a flow coordinator now returns adisposablein order to be consistent withdelay_foranddelay_until. - Calling
disposeon a server (e.g. an HTTP server) now properly closes all open connections. - Fix static assert in
expectedwhen callingtransformon an rvalue with a function object that only accepts an rvalue. - The function
caf::net::make_pipeno longer closes read/write channels of the connected socket pair on Windows. This fixes a bug where the pipe would close after two minutes of inactivity.
- Calling
to_stringon any of CAF's enum types now represents the enum value using the short name instead of the fully qualified name. For example,to_string(sec::none)now returns"none"instead of"caf::sec::none". Accordingly,from_stringnow accepts the short name (in additional to the fully qualified name). - Log format strings no longer support
%C. CAF still recognizes this option but it will always printnull. - The function
caf::telemetry::counter::incnow allows passing 0 as an argument. Previously, passing 0 triggered an assertion when building CAF with runtime checks enabled. - Calling
disposeon a flow subscription now callson_error(sec::disposed)on the observer. Previously, CAF would simply callon_complete()on the observer, making it impossible to distinguish between a normal completion and disposal. - The
caf::loggerreceived a complete overhaul and became an interface class. By turning the class into an interface, users can now install custom logger implementations. CAF uses the previous implementation as the default logger if no custom logger is configured. To install a logger, users can callcfg.logger_factory(my_logger_factory)on theactor_system_configbefore constructing theactor_system. The logger factory is a function object with signaturecaf::intrusive_ptr<caf::logger>(caf::actor_system&). Furthermore, log messages are now formatted usingstd::formatwhen compiling CAF with C++20 or later. Otherwise, CAF will fall back to a minimal formatting implementation with compatible syntax. The logging API will also automatically convert any type with a suitableinspectoverload to a string if the type is not recognized byformat.
- Calling
to_streamorto_typed_streamon an actor is now deprecated. Simply callto_streamorto_typed_streamdirectly on theobservableinstead.
- The implementation of
operator<forcaf::unordered_flat_mapwas broken and relied on the order of elements in the map. We have removed it, since it has never worked correctly and a correct implementation would be too expensive.
0.19.4 - 2023-09-29
- Stream batches are now properly serialized and deserialized when subscribing to a stream from a remote node (#1566).
0.19.3 - 2023-09-20
- The class
caf::telemetry::labelnow has a newcompareoverload that accepts acaf::telemetry::label_viewto make the interface of the both classes symmetrical. - The template class
caf::dictionarynow has new member functions for erasing elements. - The CLI argument parser now supports a space separator when using long
argument names, e.g.,
--foo bar. This is in addition to the existing--foo=barsyntax. - The functions
make_messageandmake_errornow supportstd::string_viewas input and automatically convert it tostd::string. - To make it easier to set up asynchronous flows, CAF now provides a new class:
caf::async::publisher. Any observable can be transformed into a publisher by callingto_publisher. The publisher can then be used to subscribe to the observable from other actors or threads. The publisher has only a single member function:observe_on. It converts the publisher back into an observable. This new abstraction allows users to set up asynchronous flows without having to manually deal with SPSC buffers. - The flow API received additional operators:
first,last,take_last,skip_last,element_at, andignore_elements.
- When using CAF to parse CLI arguments, the output of
--helpnow includes all user-defined options. Previously, only options in the global category or options with a short name were included. Only CAF options are now excluded from the output. They will still be included in the output of--long-help. - The output of
--dump-confignow only contains CAF options from loaded modules. Previously, it also included options from modules that were not loaded. - We renamed
caf::flow::item_publishertocaf::flow::multicasterto better reflect its purpose and to avoid confusion with the newcaf::async::publisher. - When failing to deserialize a request, the sender will receive an error of
kind
sec::malformed_message. - When implementing custom protocol layers that sit on top of an octet stream,
the
deltabyte span passed toconsumenow resets whenever returning a positive value fromconsume. - When constructing a
behaviorormessage_handler, callbacks that take amessageargument are now treated as catch-all handlers. - When creating a message with a non-existing type ID, CAF now prints a
human-readable error message and calls
abortinstead of crashing the application.
- Fix build errors with exceptions disabled.
- Fix a regression in
--dump-configthat caused CAF applications to emit malformed output. - Fix handling of WebSocket frames that are exactly on the 65535 byte limit.
- Fix crash when using a fallback value for optional values (#1427).
- Using
take(0)on an observable now properly creates an observable that callson_completeon its subscriber on the first activity of the source observable. Previously, the created observable would never reach its threshold and attempt to buffer all values indefinitely. - The comparison operator of
intrusive_ptrno longer accidentally creates newintrusive_ptrinstances when comparing to raw pointers. - Fix function object lifetimes in actions. This bug caused CAF to hold onto a strong reference to actors that canceled a timeout until the timeout expired. This could lead to actors being kept alive longer than necessary (#698).
- Key lookups in
caf::net::http::request_headerare now case-insensitive, as required by the HTTP specification. Further,field_atis now aconstmember function (#1554).
0.19.2 - 2023-06-13
- Install CAF tools to
${CMAKE_INSTALL_BINDIR}to make packaging easier. - The OpenSSL module no longer hard-codes calls to
SSL_CTX_set_cipher_listin order to use the system settings by default. Users can provide a custom cipher list by providing a value for the configuration optioncaf.openssl.cipher-list. To restore the previous behavior, set this parameter toHIGH:!aNULL:!MD5when running with a certificate andAECDH-AES256-SHA@SECLEVEL=0otherwise (or without@SECLEVEL=0for older versions of OpenSSL). Please note that these lists are not recommended as safe defaults, which is why we are no longer setting these values.
- Add missing initialization code for the new caf-net module when using the
CAF_MAINmacro. This fixes theWSANOTINITIALISEDerror on Windows (#1409). - The WebSocket implementation now properly re-assembles fragmented frames. Previously, a bug in the framing protocol implementation caused CAF to sever the connection when encountering continuation frames (#1417).
- Add new utilities in
caf::chronofor making it easier to handle ISO 8601 timestamps. The new functionstd::chrono::to_stringconverts system time to an ISO timestamp. For reading an ISO timestamp, CAF now provides the classcaf::chrono::datetime. It can parse ISO-formatted strings viaparse(ordatetime::from_string) and convert them to a local representation viato_local_time. Please refer to the class documentation for more details.
0.19.1 - 2023-05-01
- The class
json_valuecan now hold unsigned 64-bit integer values. This allows it to store values that would otherwise overflow a signed integer. Values that can be represented in both integer types will returntrueforis_integer()as well as for the newis_unsigned()function. Users can obtain the stored value asuint64_tviato_unsigned().
- With the addition of the unsigned type to
json_value, there is now a new edge case whereis_number()returnstruebut neitheris_integer()noris_double()returntrue: integer values larger thanINT64_MAXwill only return true foris_unsigned().
- Fix flow setup for servers that use
web_socket::with. This bug caused servers to immediately abort incoming connection (#1402). - Make sure that a protocol stack ships pending data before closing a socket. This bug prevented clients from receiving error messages from servers if the server shuts down immediately after writing the message.
0.19.0 - 2023-04-17
- The new classes
json_value,json_arrayandjson_objectallow working with JSON inputs directly. Actors can also pass around JSON values safely. - Futures can now convert to observable values for making it easier to process asynchronous results with data flows.
- Add new
*_weakvariants ofscheduled_actor::run_{delayed, scheduled}. These functions add no reference count to their actor, allowing it to become unreachable if other actors no longer reference it. - Typed actors that use a
typed_actor_pointercan now access therun_{delayed,scheduled}member functions. - Scheduled and delayed sends now return a disposable (#1362).
- Typed response handles received support for converting them to observable or single objects.
- Typed actors that use the type-erased pointer-view type received access to the
new flow API functions (e.g.,
make_observable). - Not initializing the meta objects table now prints a diagnosis message before
aborting the program. Previously, the application would usually just crash due
to a
nullptr-access inside some CAF function. - The class
expectednow implements the monadic member functions from C++23std::expectedas well asvalue_or.
- After collecting experience and feedback on the new HTTP and WebSocket APIs introduced with 0.19.0-rc.1, we decided to completely overhaul the user-facing, high-level APIs. Please consult the manual for the new DSL to start servers.
- When exporting metrics to Prometheus, CAF now normalizes label names to meet
the Prometheus name requirements, e.g.,
label-1becomeslabel_1(#1386). - The SPSC buffer now makes sure that subscribers get informed of a producer has already left before the subscriber appeared and vice versa. This fixes a race on the buffer that could cause indefinite hanging of an application.
- Fused stages now properly forward errors during the initial subscription to their observer.
- The
fan_out_requestrequest now properly deals with actor handles that respond withvoid(#1369). - Fix subscription and event handling in flow buffer operator.
- The
mcastanducastoperators now stop callingon_nextimmediately when disposed. - Actors no longer terminate despite having open streams (#1377).
- Actors reading from external sources such as SPSC buffers via a local flow could end up in a long-running read loop. To avoid potentially starving other actors or activities, scheduled actors now limit the amount of actions that may run in one iteration (#1364).
- Destroying a consumer or producer resource before opening it lead to a stall
of the consumer / producer. The buffer now keeps track of whether
closeorabortwere called prior to consumers or producers attaching. - The function
caf::net::make_tcp_accept_socketnow handles passing0.0.0.0correctly by opening the socket in IPv4 mode. Passing an empty bind address now defaults toINADDR6_ANY(but allowing IPv4 clients) withINADDR_ANYas fallback in case opening the socket in IPv6 mode failed. - Add missing includes that prevented CAF from compiling on GCC 13.
- Fix AddressSanitizer and LeakSanitizer findings in some flow operators.
- All member functions from
caf::expectedthat have no equivalent instd::expectedare now deprecated. Further,caf::expected<unit_t>as well as constructing fromunit_tare deprecated as well. The reasoning behind this decision is thatcaf::expectedshould eventually become an alias forstd::expected<T, caf::error>.
0.19.0-rc.1 - 2022-10-31
- CAF now ships an all-new "flow API". This allows users to express data flows at a high level of abstraction with a ReactiveX-style interface. Please refer to new examples and the documentation for more details, as this is a large addition that we cannot cover in-depth here.
- CAF has received a new module:
caf.net. This module enables CAF applications to interface with network protocols more directly thancaf.io. The new module contains many low-level building blocks for implementing bindings to network protocols. However, CAF also ships ready-to-use, high-level APIs for WebSocket and HTTP. Please have a look at our new examples that showcase the new APIs! - To complement the flow API as well as the new networking module, CAF also
received a new set of
asyncbuilding blocks. Most notably, this includes asynchronous buffers for the flow API and futures / promises that enable the new HTTP request API. We plan on making these building blocks more general in the future for supporting a wider range of use cases. - JSON inspectors now allow users to use a custom
type_id_mapperto generate and parse JSON text that uses different names for the types than the C++ API.
- Passing a response promise to a run-delayed continuation could result in a heap-use-after-free if the actor terminates before the action runs. The destructor of the promise now checks for this case.
- Accessing URI fields now always returns the normalized string.
- Module options (e.g. for the
middleman) now show up in--long-helpoutput. - Fix undefined behavior in the Qt group chat example (#1336).
- The
..._instanceconvenience functions on the registry metric now properly supportdoublemetrics and histograms. - The spinlock-based work-stealing implementation had severe performance issues on Windows in some cases. We have switched to a regular, mutex-based approach to avoid performance degradations. The new implementation also uses the mutexes for interruptible waiting on the work queues, which improves the responsiveness of the actor system (#1343).
- Remote spawning of actors is no longer considered experimental.
- The output of
--dump-confignow prints valid config file syntax. - When starting a new thread via CAF, the thread hooks API now receives an additional tag that identifies the component responsible for launching the new thread.
- Response promises now hold a strong reference to their parent actor to avoid
broken_promiseerrors in some (legitimate) edge cases (#1361). - The old, experimental
streamAPI in CAF has been replaced by a new API that is based on the new flow API.
- The obsolete meta-programming utilities
replies_toandreacts_tono longer serve any purpose and are thus deprecated. - The types
caf::byte,caf::optionalandcaf::string_viewbecame obsolete after switching to C++17. Consequently, these types are now deprecated in favor of their standard library counterpart. - The group-based pub/sub mechanism never fit nicely into the typed messaging API and the fact that group messages use the regular mailbox makes it hard to separate regular communication from multi-cast messages. Hence, we decided to drop the group API and instead focus on the new flows and streams that can replace group-communication in many use cases.
- The "actor-composition operator" was added as a means to enable the first experimental streaming API. With that gone, there's no justification to keep this feature. While it has some neat niche-applications, the prevent some optimization we would like to apply to the messaging layer. Hence, we will remove this feature without a replacement.
- The template type
caf::variantalso became obsolete when switching to C++17. Unfortunately, the implementation was not as standalone as its deprecated companions and some of the free functions likeholds_alternativewere too greedy and did not play nicely with ADL when usingstd::variantin the same code base. Since fixingcaf::variantdoes not seem to be worth the time investment, we remove this type without a deprecation cycle.
0.18.7 - 2023-02-08
- The JSON parser no longer chokes when encountering
nullas last value before the closing parenthesis. - The JSON reader now automatically widens integers to doubles as necessary.
- Parsing deeply nested JSON inputs no longer produces a stack overflow. Instead, the parser rejects any JSON with too many nesting levels.
- The
fan_out_requestrequest now properly deals with actor handles that respond withvoid(#1369). Note: back-ported fix from 0.19.
0.18.6 - 2022-03-24
- When adding CAF with exceptions enabled (default), the unit test framework now
offers new check macros:
CAF_CHECK_NOTHROW(expr)CAF_CHECK_THROWS_AS(expr, type)CAF_CHECK_THROWS_WITH(expr, str)CAF_CHECK_THROWS_WITH_AS(expr, str, type)
- The DSL function
run_untilmiscounted the number of executed events, also causingrun_onceto report a wrong value. Both functions now return the correct result. - Using
allow(...).with(...)in unit tests without a matching message crashed the program. By adding a missing NULL-check,allowis now always safe to use. - Passing a response promise to a run-delayed continuation could result in a heap-use-after-free if the actor terminates before the action runs. The destructor of the promise now checks for this case.
- Fix OpenSSL 3.0 warnings when building the OpenSSL module by switching to newer EC-curve API.
- When working with settings,
put,put_missing,get_if, etc. now gracefully handle theglobalcategory when explicitly using it. - Messages created from a
message_builderdid not call the destructors for their values, potentially causing memory leaks (#1321).
- Since support of Qt 5 expired, we have ported the Qt examples to version 6. Hence, building the Qt examples now requires Qt in version 6.
- When compiling CAF with exceptions enabled (default),
REQUIRE*macros,expectanddisallowno longer callabort(). Instead, they throw an exception that only stops the current test instead of stopping the entire test program. - Reporting of several unit test macros has been improved to show correct line numbers and provide better diagnostic of test errors.
0.18.5 - 2021-07-16
- 0.18.4 introduced a potential crash when using the OpenSSL module and
encountering
SSL_ERROR_WANT_READ. The crash manifested if CAF resumed a write operation but failed to fully reset its state. The state management (and consequently the crash) has been fixed. - CAF now clears the actor registry before calling the destructors of loaded modules. This fixes undefined behavior that could occur in rare cases where actor cleanup code could run after loaded modules had been destroyed.
0.18.4 - 2021-07-07
- The new class
caf::telemetry::importer::processallows users to get access to process metrics even when not configuring CAF to export metrics to Prometheus via HTTP.
- Message views now perform the type-check in their constructor. With this
change, the
make_*utility functions are no longer mandatory and users may instead simply construct the view directly.
- Printing a
config_valuethat contains a zero durationtimespannow properly prints0sinstead of1s(#1262). This bug most notably showed up when setting atimespanparameter such ascaf.middleman.heartbeat-intervalvia config file or CLI to0sand then printing the config parameter, e.g., via--dump-config. - Blocking actors now release their private thread before decrementing the running-actors count to resolve a race condition during system shutdown that could result in the system hanging (#1266).
- When using the OpenSSL module, CAF could run into a state where the SSL layer
wants to read data while CAF is trying to send data. In this case, CAF did not
properly back off, causing high CPU load due to spinning and in some scenarios
never recovering. This issue has been resolved by properly handling
SSL_ERROR_WANT_READon the transport (#1060). - Scheduled actors now accept default handlers for down messages etc. with
non-const apply operator such as lambda expressions declared as
mutable.
- Dropped three obsolete (and broken) macros in the
unit_test.hppheader:CAF_CHECK_FAILED,CAF_CHECK_FAILandCAF_CHECK_PASSED.
0.18.3 - 2021-05-21
- The
actor_system_confignow has an additional member calledconfig_file_path_alternatives. With this, users can configure fallback paths for locating a configuration file. For example, an applicationmy-appon a UNIX-like system could setconfig_file_pathtomy-app.confand then add/etc/my-app.conftoconfig_file_path_alternativesin order to follow the common practice of looking into the current directory first before looking for a system-wide configuration file.
- Counters in histogram buckets are now always integers, independently on the value type of the histogram. Buckets can never increase by fractional values.
- All
parsefunction overloads inactor_system_configthat took a custom configuration file path as argument were deprecated in favor of consistently asking users to use theconfig_file_pathandconfig_file_path_alternativesmember variables instead
- For types that offer implicit type conversion, trying to construct a
result<T>could result in ambiguity since compilers could construct eitherTitself orexpected<T>for calling a constructor ofresult<T>. To fix the ambiguity,result<T>now accepts any type that allows constructing aTinternally without requiring a type conversion toTas an argument (#1245). - Fix configuration parameter lookup for the
work-stealingscheduler policy. - Applications that expose metrics to Prometheus properly terminate now.
0.18.2 - 2021-03-26
- CAF includes two new inspector types for consuming and generating
JSON-formatted text:
json_writerandjson_reader.
- Setter functions for fields may now return either
bool,caf::errororvoid. Previously, CAF only allowedbool.
- Passing a getter and setter pair to an inspector via
applyproduced a compiler error for non-builtin types. The inspection API now recursively inspects user-defined types instead, as was the original intend (#1216). - The handle type
typed_actornow can construct from atyped_actor_pointer. This resolves a compiler error when trying to initialize a handle formy_handlefrom a self pointer of typemy_handle::pointer_view(#1218). - Passing a function reference to the constructor of an actor caused a compiler
error when building with logging enabled. CAF now properly handles this edge
case and logs such constructor arguments as
<unprintable>(#1229). - The CLI parser did not recognize metrics filters. Hence, passing
--caf.metrics-filters.actors.includes=...to a CAF application resulted in an error. Theincludesandexcludesfilters are now consistently handled and accepted in config files as well as on the command line (#1238). - Silence a deprecated-enum-conversion warning for
std::byte(#1230). - Fix heap-use-after-free when accessing the meta objects table in applications
that leave the
mainfunction while the actor system and its worker threads are still running (#1241). - The testing DSL now properly accounts for the message prioritization of actors
(suspending regular behavior until receiving the response) when using
request.await(#1232).
0.18.1 - 2021-03-19
- Version 0.18.0 introduced a regression on the system parameter
caf.middleman.heartbeat-interval(#1235). We have addressed the issue by porting the original fix for CAF 0.17.5 (#1095) to the 0.18 series.
0.18.0 - 2021-01-25
- The enum
caf::secreceived an additional error code:connection_closed. - The new
byte_spanandconst_byte_spanaliases provide convenient definitions when working with sequences of bytes. - The base metrics now include four new histograms for illuminating the I/O
module:
caf.middleman.inbound-messages-size,caf.middleman.outbound-messages-size,caf.middleman.deserialization-timeandcaf.middleman.serialization-time. - The macro
CAF_ADD_TYPE_IDnow accepts an optional third parameter for allowing users to override the default type name. - The new function pair
get_asandget_ormodel type conversions on aconfig_value. For example,get_as<int>(x)would convert the content ofxto anintby either casting numeric values toint(with bound checks) or trying to parse the input ofxif it contains a string. The functionget_oralready existed forsettings, but we have added new overloads for generalizing the function toconfig_valueas well. - The
typed_response_promisereceived additional member functions to mirror the interface of the untypedresponse_promise. - Configuration files now allow dot-separated notation for keys. For example,
users may write
caf.scheduler.max-threads = 4instead of the nested formcaf { scheduler { max-threads = 4 } }.
- The new
get_asandget_orfunction pair makes type conversions on aconfig_valueviaget,get_if, etc. obsolete. We will retain the STL-style interface for treating aconfig_valueas avariant-like type.
- When using
CAF_MAIN, CAF now looks for the correct default config file name, i.e.,caf-application.conf. - Simplify the type inspection API by removing the distinction between
apply_objectandapply_value. Instead, inspectors only offerapplyand users may now also callmap,list, andtuplefor unboxing simple wrapper types. Furthermore, CAF no longer automatically serializes enumeration types using their underlying value because this is fundamentally unsafe. - CAF no longer parses the input to string options on the command line. For
example,
my_app '--msg="hello"'results in CAF storing"hello"(including the quotes) for the config optionmsg. Previously, CAF tried to parse any string input on the command-line that starts with quotes in the same way it would parse strings from a config file, leading to very unintuitive results in some cases (#1113). - Response promises now implicitly share their state when copied. Once the
reference count for the state reaches zero, CAF now produces a
broken_promiseerror if the actor failed to fulfill the promise by calling eitherdispatchordelegate.
- Setting an invalid credit policy no longer results in a segfault (#1140).
- Version 0.18.0-rc.1 introduced a regression that prevented CAF from writing parameters parsed from configuration files back to variables. The original behavior has been restored, i.e., variables synchronize with user input from configuration files and CLI arguments (#1145).
- Restore correct functionality of
middleman::remote_lookup(#1146). This fixes a regression introduced in version 0.18.0-rc.1 - Fixed an endless recursion when using the
default_inspectorfrominspectoverloads (#1147). - CAF 0.18 added support for
make_behaviorin state classes. However, CAF erroneously picked this member function over running the function body when spawning function-based actors (#1149). - When passing
nullptror custom types with implicit conversions toconst char*todeep_to_string, CAF could run into a segfault in the former case or do unexpected things in the latter case. The stringification inspector now matches precisely on pointer types to stop the compiler from doing implicit conversions in the first place. - Building executables that link to CAF on 32-bit Linux versions using GCC
failed due to undefined references to
__atomic_fetchsymbols. Adding a CMake dependency forcaf_coreto libatomic gets executables to compile and link as expected (#1153). - Fixed a regression for remote groups introduced in 0.18.0-rc.1 (#1157).
- CAF 0.18 introduced the option to set different
excluded-componentsfilters for file and console log output. However, CAF rejected all events that matched either filter. The new implementation uses the intersection of both filters to reject log messages immediately (before enqueueing it to the logger's queue) and then applies the filters individually when generating file or console output. - Fix memory leaks when deserializing URIs and when detaching the content of messages (#1160).
- Fix undefined behavior in
string_view::compare(#1164). - Fix undefined behavior when passing
--config-file=(i.e., without actual argument) to CAF applications (#1167). - Protect against self-assignment in a couple of CAF classes (#1169).
- Skipping high-priority messages resulted in CAF lowering the priority to normal. This unintentional demotion has been fixed (#1171).
- Fix undefined behavior in the experimental datagram brokers (#1174).
- Response promises no longer send empty messages in response to asynchronous messages.
CAF_ADD_TYPE_IDnow works with types that live in namespaces that also exist as nested namespace in CAF such asdetailorio(#1195).- Solved a race condition on detached actors that blocked ordinary shutdown of actor systems in some cases (#1196).
0.18.0-rc.1 - 2020-09-09
- The new
fan_out_requestfunction streamlines fan-out/fan-in work flows (see the new example inexamples/message_passing/fan_out_request.cppas well as the new manual entry). The policy-based design further allows us to support more use cases in the future (#932, #964). - We introduced the lightweight template class
error_codeas an alternative to the generic but more heavyweight classerror. The new error code abstraction simply wraps an enumeration type without allowing users to add additional context such as error messages. However, whenever such information is unneeded, the new class is much more efficient than usingerror. - Tracing messages in distributed systems is a common practice for monitoring
and debugging message-based systems. The new
tracing_dataabstraction in CAF enables users to augment messages between actors with arbitrary meta data. This is an experimental API that requires building CAF with the CMake optionCAF_ENABLE_ACTOR_PROFILER(#981). - Add compact
from..to..steplist notation in configuration files. For example,[1..3]expands to[1, 2, 3]and[4..-4..-2]expands to[4, 2, 0, -2, -4](#999). - Allow config keys to start with numbers (#1014).
- The
fan_out_requestfunction got an additional policy for picking just the fist result:select_any(#1012). - Run-time type information in CAF now uses 16-bit type IDs. Users can assign
this ID by specializing
type_idmanually (not recommended) or use the new API for automatically assigning ascending IDs insideCAF_BEGIN_TYPE_ID_BLOCKandCAF_END_TYPE_ID_BLOCKcode blocks. - The new typed view types
typed_message_viewandconst_typed_message_viewmake working withmessageeasier by providing astd::tuple-like interface (#1034). - The class
exit_msgfinally got its missingoperator==(#1039). - The class
node_idreceived an overload forparseto allow users to convert the output ofto_stringback to the original ID (#1058). - Actors can now
monitoranddemonitorCAF nodes (#1042). Monitoring a CAF node causes the actor system to send anode_down_msgto the observer when losing connection to the monitored node. - In preparation of potential future API additions/changes, CAF now includes an
RFC4122-compliant
uuidclass. - The new trait class
is_error_code_enumallows users to enable conversion of custom error code enums toerroranderror_code. - CAF now enables users to tap into internal CAF metrics as well as adding their own instrumentation! Since this addition is too large to cover in a changelog entry, please have a look at the new Metrics Section of the manual to learn more.
- The
to_stringoutput forerrornow renders the error code enum by default. This renders the member functionsactor_system::renderandactor_system_config::renderobsolete. - Actors that die due to an unhandled exception now use
sec::runtime_errorconsistently. This makesexit_reason::unhandled_exceptionobsolete.
- CAF now requires C++17 to build.
- On UNIX, CAF now uses visibility hidden by default. All API functions and types that form the ABI are explicitly exported using module-specific macros. On Windows, this change finally enables building native DLL files.
- We switched our coding style to the C++17 nested namespace syntax.
- CAF used to generate the same node ID when running on the same machine and only differentiates actors systems by their process ID. When running CAF instances in a container, this process ID is most likely the same for each run. This means two containers can produce the same node ID and thus equivalent actor IDs. In order to make it easier to use CAF in a containerized environment, we now generate unique (random) node IDs (#970).
- We did a complete redesign of all things serialization. The central class
data_processorgot removed. The two classes for binary serialization no longer extend the generic interfacesserializeranddeserializerin order to avoid the overhead of dynamic dispatching as well as the runtime cost oferrorreturn values. This set of changes leads so some code duplication, because many CAF types now accept a generic(de)serializeras well as abinary_(de)serializerbut significantly boosts performance in the hot code paths of CAF (#975). - With C++17, we no longer support compilers without support for
thread_local. Consequently, we removed all workarounds and switched to the C++ keyword (#996). - Our manual now uses
reStructuredTextinstead ofLaTeX. We hope this makes extending the manual easier and lowers the barrier to entry for new contributors. - A
stateful_actornow forwards excess arguments to theStaterather than to theBase. This enables states with non-default constructors. When usingstateful_actor<State>as pointer type in function-based actors, nothing changes (i.e. the new API is backwards compatible for this case). However, callingspawn<stateful_actor<State>>(xs...)now initializes theStatewith the argument packxs...(plus optionally aselfpointer as first argument). Furthermore, the state class can now provide amake_behaviormember function to initialize the actor (this has no effect for function-based actors). - In order to stay more consistent with naming conventions of the standard
library, we have renamed some values of the
pecenumeration:illegal_escape_sequence=>invalid_escape_sequenceillegal_argument=>invalid_argumentillegal_category=>invalid_category
- CAF no longer automagically flattens
tuple,optional, orexpectedwhen returning these types from message handlers. Users can simply replacestd::tuple<A, B, C>withcaf::result<A, B, C>for returning more than one value from a message handler. - A
caf::resultcan no longer representskip. Whether a message gets skipped or not is now only for the default handler to decide. Consequently, default handlers now returnskippable_resultinstead ofresult<message>. A skippable result is a variant overdelegated<message>,message,error, orskip_t. The only good use case for message handlers that skip a message in their body was in typed actors for getting around the limitation that a typed behavior always must provide all message handlers (typed behavior assume a complete implementation of the interface). This use case received direct support: constructing a typed behavior withpartial_behavior_initas first argument suppresses the check for completeness. - In order to reduce complexity of typed actors, CAF defines interfaces as a set
of function signatures rather than using custom metaprogramming facilities.
Function signatures must always wrap the return type in a
result<T>. For example:typed_actor<result<double>(double)>. We have reimplemented the metaprogramming facilitiesracts_to<...>andreplies_to<...>::with<...>as an alternative way of writing the function signature. - All parsing functions in
actor_system_configthat take an input stream exclusively use the new configuration syntax (please consult the manual for details and examples for the configuration syntax). - The returned string of
name()must not change during the lifetime of an actor. Hence,stateful_actornow only considers staticnamemembers in itsStatefor overriding this function. CAF always assumed names belonging to types, but did not enforce it because the name was only used for logging. Since the new metrics use this name for filtering now, we enforce static names in order to help avoid hard-to-find issues with the filtering mechanism. - The type inspection API received a complete overhaul. The new DSL for writing
inspectfunctions exposes the entire structure of an object to CAF. This enables inspectors to read and write a wider range of data formats. In particular human-readable, structured data such as configuration files, JSON, XML, etc. The inspection API received too many changes to list them here. Please refer to the manual section on type inspection instead.
- A vendor-neutral API for GPGPU programming sure sounds great. Unfortunately,
OpenCL did not catch on in the way we had hoped. At this point, we can call
OpenCL dead and gone. There is only legacy support available and recent
versions of the standard were never implemented in the first place.
Consequently, we've dropped the
openclmodule. - The old
durationtype is now superseded bytimespan(#994). - The enum
match_resultbecame obsolete. Individual message handlers can no longer skip messages. Hence, message handlers can only succeed (match) or not. Consequently, invoking a message handler or behavior now returns a boolean. - All member functions of
scheduled_actorfor adding stream managers (such asmake_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
.inifiles. 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 iscaf-application.conf.
- Fix uninstall target when building CAF as CMake subdirectory.
- Using
inline_all_enqueuesin deterministic unit tests could result in deadlocks when calling blocking functions in message handlers. This function now behaves as expected (#1016). - Exceptions while handling requests now trigger error messages (#1055).
- The member function
demonitorfalsely refused typed actor handles. Actors could monitor typed actors but not demonitoring it again. This member function is now a template that accepts any actor handle in the same waymonitoralready did. - The
typed_actor_viewdecorator lacked several member functions such aslink_to,send_exit, etc. These are now available. - Constructing a
typed_actorhandle from a pointer view failed due to a missing constructor overload. This (explicit) overload now exists and the conversion should work as expected. - Sending floating points to remote actors changed
infinityandNaNto garbage values (#1107). The fixed packing / unpacking routines for IEEE 754 values keep these non-numeric values intact now. It is worth mentioning that the new algorithm downgrades signaling NaN values to silent NaN values, because the standard API does not provide predicates to distinguish between the two. This should have no implications for real-world applications, because actors that produce a signaling NaN trigger trap handlers before sending the result to another actor. - The URI parser stored IPv4 addresses as strings (#1123). Users can now safely
assume that the parsed URI for
tcp://127.0.0.1:8080returns an IP address when callingauthority().host.
0.17.7 - Unreleased
- Datagram servants of UDP socket managers were not added as children to their parent broker on creation, which prevented proper system shutdown in some cases. Adding all servants consistently to the broker should make sure UDP brokers terminate correctly (#1133).
- Backport stream manager fix from CAF 0.18 for fused downstream managers that prevent loss of messages during regular actor shutdown.
0.17.6 - 2020-07-24
- Trying to connect to an actor published via the OpenSSL module with the I/O module no longer hangs indefinitely (#1119). Instead, the OpenSSL module immediately closes the socket if initializing the SSL session fails.
0.17.5 - 2020-05-13
- In order to allow users to start migrating towards upcoming API changes, CAF
0.17.5 includes a subset of the CAF 0.18
type_idAPI. Listing all user-defined types betweenCAF_BEGIN_TYPE_ID_BLOCKandCAF_END_TYPE_ID_BLOCKassigns ascending type IDs. Only one syntax forCAF_ADD_ATOMexists, since the atom text is still mandatory. Assigning type IDs has no immediate effect by default. However, the new functionactor_system_config::add_message_typesaccepts an ID block and adds runtime-type information for all types in the block. - In order to opt into the compile-time checks for all message types, users can
set the
CAF_ENABLE_TYPE_ID_CHECKSCMake flag toON(pass--enable-type-id-checkswhen using theconfigurescript). Building CAF with this option causes compiler errors when sending a type without a type ID. This option in conjunction with the newadd_message_typesfunction removes a common source of bugs: forgetting to calladd_message_type<T>for all types that can cross the wire.
- Our manual now uses
reStructuredTextinstead ofLaTeX(backport from 0.18.0).
- Fix handling of OS-specific threading dependency in CMake.
- Fix uninstall target when building CAF as CMake subdirectory (backport from 0.18.0).
- Fix potential deadlock with
inline_all_enqueues(backport from 0.18.0). - Exceptions while handling requests now trigger error messages (backport from 0.18.0).
- Fix build on GCC 7.2
- Fix build error in the OpenSSL module under some MSVC configurations
- Serializer and deserializer now accept
std::chrono::time_pointfor all clock types instead of hard-wiringstd::system_clock. - In some edge cases, actors failed to shut down properly when hosting a stream source (#1076). The handshake process for a graceful shutdown has been fixed.
- Fixed a compiler error on Clang 10 (#1077).
- Setting lists and dictionaries on the command line now properly overrides default values and values from configuration files instead of appending to them (#942).
- Using unquoted strings in command-line arguments inside lists now works as
expected. For example,
--foo=abc,defis now equivalent to--foo=["abc", "def"]. - Fixed a type mismatch in the parameter
middleman.heartbeat-interval(#1095). CAF consistently usestimespanfor this parameter now.
0.17.4 - 2019-02-08
- The class
exit_msgfinally got its missingoperator==(#1039, backport from 0.18.0).
- Make sure actors that receive stream input shut down properly (#1019).
- Improve
to_stringoutput forcaf::error(#1021). - Properly report errors to users while connecting two CAF nodes (#1023).
- Simplify crosscompilation: remove build dependency on code generators (#1026).
- Leave CXX settings to the (CMake) parent when building as subdirectory (#1032).
- Build without documentation in subdirectory mode (#1037).
- Allow parents to set
OPENSSL_INCLUDE_DIRin subdirectory mode (#1037). - Add
-pthreadflag on UNIX when looking forlibc++support (#1038). - Avoid producing unexpected log files (#1024).
- Accept numbers as keys in the config syntax (#1014).
- Fix undesired function hiding in
fused_downstream_manager(#1020). - Fix behavior of
inline_all_enqueuesin the testing DSL (#1016). - Fix path recognition in the URI parser, e.g.,
file:///is now valid (#1013).
0.17.3 - 2019-11-11
- Add support for OpenBSD (#955).
- Provide uniform access to actor properties (#958).
- Add missing
to_string(pec)(#940).
- Fix bug in stream managers that caused finalizers to get called twice (#937).
- Fix verbosity level with disabled console output (#953).
- Fix excessive buffering in stream stages (#952).
0.17.2 - 2019-10-20
- Add
scheduled_sendfor delayed sends with absolute timeout (#901). - Allow actors based on composable behaviors to use the streaming API (#902).
- Support arbitrary list and map types in
config_value(#925). - Allow users to extend the
config_valueAPI (#929, #938).
- Reduce stack usage of serializers (#912).
- Use default installation directories on GNU/Linux (#917).
- Fix memory leak when deserializing
node_id(#905). - Fix composition of statically typed actors using streams (#908).
- Fix several warnings on GCC and Clang (#915).
- Fix
holds_alternativeandget_ifforsettings(#920). - Fix silent dropping of errors in response handlers (#935).
- Fix stall in
remote_groupon error (#933).
0.17.1 - 2019-08-31
- Support nesting of group names in .ini files (#870).
- Support all alphanumeric characters in config group names (#869).
- Improve CMake setup when building CAF as subfolder (#866).
- Properly set CLI remainder (#871).
- Fix endless loop in config parser (#894).
- Fix debug build with Clang 7 on Linux (#861).
- Fix type-specific parsing of config options (#814).
- Fix potential deadlock in proxy registry (#880).
- Fix output of --dump-config (#876).
- Fix potential segfault when using streams with trace logging enabled (#878).
- Fix handling of containers with user-defined types (#867).
- Fix
defaulted_function_deletedwarning on Clang (#859).
0.17.0 - 2019-07-27
- Add marker to make categories optional on the CLI. Categories are great at
organizing program options. However, on the CLI they get in the way quickly.
This change allows developers to prefix category names with
?to make it optional on the CLI. - Add conversion from
nullptrto intrusive and COW pointer types. - Support move-only behavior functions.
- Allow users to omit
globalin config files. - Allow IPO on GCC/Clang.
- Parallelize deserialization of messages received over the network (#821). Moving the deserialization out of the I/O loop significantly increases performance. In our benchmark, CAF now handles up to twice as many messages per second.
- Relax ini syntax for maps by making
=for defining maps and,for separating key-value pairs optional. For example, this change allows to rewrite an entry like this:to a slightly less noisy version such as this:logger = { console-verbosity='trace', console='colored' }
logger { console-verbosity='trace' console='colored' } - Allow apps to always use the
logger, whether or not CAF was compiled with logging enabled. - Streamline direct node-to-node communication and support multiple app identifiers.
- Reimplement
binary_serializerandbinary_deserializerwithout STL-style stream buffers for better performance.
- Fix performance of the thread-safe actor clock (#849). This clock type is used whenever sending requests, delayed messages, receive timeouts etc. With this change, CAF can handle about 10x more timeouts per second.
- Fix multicast address detection in
caf::ipv4_address.cpp(#853). - Fix disconnect issue / WSAGetLastError usage on Windows (#846).
- Fix
--config-fileoption (#841). - Fix parsing of CLI arguments for strings and atom values.
0.16.5 - 2019-11-11
- Support for OpenBSD.
0.16.4 - 2019-11-11
- Backport parser fixes from the CAF 0.17 series.
- Silence several compiler warnings on GCC and Clang.
0.16.3 - 2018-12-27
- The new class
cow_tupleprovides anstd::tuple-like interface for a heap-allocated, copy-on-write tuple. - Missing overloads for
dictionary. - The new
to_lowercasefunction for atoms allows convenient conversion without having to convert between strings and atoms.
- Printing timestamps now consistently uses ISO 8601 format.
- The logger now uses a bounded queue. This change in behavior will cause the application to slow down when logging faster than the logger can do I/O, but the queue can no longer grow indefinitely.
- Actors now always try to dequeue from the high-priority queue first.
- Solved linker errors related to
socket_guardin some builds. - Fix the logger output for class names.
- Deserializing into non-empty containers appended to the content instead of overriding it. The new implementation properly clears the container before filling it.
- The
splitfunction from the string algorithms header now works as the documentation states. - Silence several compiler warnings on GCC and Clang.
0.16.2 - 2018-11-03
- The copy-on-write pointer used by
messagefailed to release memory in some cases. The resulting memory leak is now fixed.
0.16.1 - 2018-10-31
- Adding additional flags for the compiler when using the
configurescript is now easier thanks to the--extra-flags=option. - The actor clock now supports non-overriding timeouts.
- The new
intrusive_cow_ptris a smart pointer for copy-on-write access.
- Improve
noexcept-correctness ofvariant. - CAF threads now have recognizable names in a debugger.
- The middleman now passes
CLOEXEConsocket/accept/pipecalls. - Users can now set the log verbosity for file and console output separately.
- A
dictionarynow properly treats C-strings as strings when usingemplace. - Eliminate a potential deadlock in the thread-safe actor clock.
- Added various missing includes and forward declarations.
0.16.0 - 2018-09-03
- As part of CE-0002,
config_valuereceived support for lists, durations and dictionaries. CAF now exposes the content of an actor system config as a dictionary ofconfig_value. The free functionget_oroffers convenient access to configuration parameters with hard-coded defaults as fallback. - The C++17-compatible
string_viewclass enables us to make use of recent standard addition without having to wait until it becomes widely available. - In preparation of plans for future convenience API, we've added
uriaccording to RFC 3986 as well asipv6_addressandipv4_address. - A new, experimental streaming API. Please have a look at the new manual section for more details.
- Going forward, the preferred way to access configuration parameters is using
the new
get_orAPI. Hence, these member variables are now deprecated inactor_system_config:scheduler_policyscheduler_max_threadsscheduler_max_throughputscheduler_enable_profilingscheduler_profiling_ms_resolutionscheduler_profiling_output_filework_stealing_aggressive_poll_attemptswork_stealing_aggressive_steal_intervalwork_stealing_moderate_poll_attemptswork_stealing_moderate_steal_intervalwork_stealing_moderate_sleep_duration_uswork_stealing_relaxed_steal_intervalwork_stealing_relaxed_sleep_duration_uslogger_file_namelogger_file_formatlogger_consolelogger_console_formatlogger_verbositylogger_inline_outputmiddleman_network_backendmiddleman_app_identifiermiddleman_enable_automatic_connectionsmiddleman_max_consecutive_readsmiddleman_heartbeat_intervalmiddleman_detach_utility_actorsmiddleman_detach_multiplexermiddleman_cached_udp_buffersmiddleman_max_pending_msgs
- The
boost::asiowas part of an initiative to contribute CAF asboost::actor. Since there was little interest by the Boost community, this backend now serves no purpose.
- Setting the log level to
quietnow properly suppresses any log output. - Configuring colored terminal output should now print colored output.