Skip to content


Choose a tag to compare
@Neverlord Neverlord released this 09 Sep 15:54
· 1867 commits to master since this release


  • The new fan_out_request function streamlines fan-out/fan-in work flows (see
    the new example in examples/message_passing/fan_out_request.cpp as 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_code as an alternative to
    the generic but more heavyweight class error. 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 using error.
  • Tracing messages in distributed systems is a common practice for monitoring
    and debugging message-based systems. The new tracing_data abstraction 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 option
  • Add compact list 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_request function 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_id manually (not recommended) or use the new
    API for automatically assigning ascending IDs inside CAF_BEGIN_TYPE_ID_BLOCK
    and CAF_END_TYPE_ID_BLOCK code blocks.
  • The new typed view types typed_message_view and const_typed_message_view
    make working with message easier by providing a std::tuple-like interface
  • The class exit_msg finally got its missing operator== (#1039).
  • The class node_id received an overload for parse to allow users to convert
    the output of to_string back to the original ID (#1058).
  • Actors can now monitor and demonitor CAF nodes (#1042). Monitoring a CAF
    node causes the actor system to send a node_down_msg to the observer when
    losing connection to the monitored node.
  • In preparation of potential future API additions/changes, CAF now includes an
    RFC4122-compliant uuid class.
  • The new trait class is_error_code_enum allows users to enable conversion of
    custom error code enums to error and error_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


  • 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.
  • Actors that die due to an unhandled exception now use sec::runtime_error
    consistently. This makes exit_reason::unhandled_exception obsolete.


  • 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_processor got removed. The two classes for binary serialization no
    longer extend the generic interfaces serializer and deserializer in order
    to avoid the overhead of dynamic dispatching as well as the runtime cost of
    error return values. This set of changes leads so some code duplication,
    because many CAF types now accept a generic (de)serializer as well as a
    binary_(de)serializer but 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
  • Our manual now uses reStructuredText instead of LaTeX. We hope this makes
    extending the manual easier and lowers the barrier to entry for new
  • A stateful_actor now forwards excess arguments to the State rather than to
    the Base. This enables states with non-default constructors. When using
    stateful_actor<State> as pointer type in function-based actors, nothing
    changes (i.e. the new API is backwards compatible for this case). However,
    calling spawn<stateful_actor<State>>(xs...) now initializes the State with
    the argument pack xs... (plus optionally a self pointer as first
    argument). Furthermore, the state class can now provide a make_behavior
    member function to initialize the actor (this has no effect for function-based
  • In order to stay more consistent with naming conventions of the standard
    library, we have renamed some values of the pec enumeration:
    • illegal_escape_sequence => invalid_escape_sequence
    • illegal_argument => invalid_argument
    • illegal_category => invalid_category
  • CAF no longer automagically flattens tuple, optional, or expected when
    returning these types from message handlers. Users can simply replace
    std::tuple<A, B, C> with caf::result<A, B, C> for returning more than one
    value from a message handler.
  • A caf::result can no longer represent skip. Whether a message gets skipped
    or not is now only for the default handler to decide. Consequently, default
    handlers now return skippable_result instead of result<message>. A
    skippable result is a variant over delegated<message>, message, error,
    or skip_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 with partial_behavior_init as 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 facilities racts_to<...> and replies_to<...>::with<...>
    as an alternative way of writing the function signature.
  • All parsing functions in actor_system_config that 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_actor now only considers static name members in its
    State for 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
    inspect functions 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 opencl module.
  • The old duration type is now superseded by timespan (#994).
  • The enum match_result became 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_actor for adding stream managers (such as
    make_source) were removed in favor their free-function equivalent, e.g.,
  • 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.


  • Fix uninstall target when building CAF as CMake subdirectory.
  • Using inline_all_enqueues in 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 demonitor falsely 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 way monitor
    already did.
  • The typed_actor_view decorator lacked several member functions such as
    link_to, send_exit, etc. These are now available.
  • Constructing a typed_actor handle from a pointer view failed du to a missing
    constructor overload. This (explicit) overload now exists and the conversion
    should work as expected.
  • Sending floating points to remote actors changed infinity and NaN to
    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:// returns an IP address
    when calling authority().host.