Skip to content

Commit 29153f6

Browse files
committed
Asio completion token support and thread-safe Session operations
- All asynchronous operations in Session now accept a generic completion token. - C++20 coroutines now supported by Session. - Added examples using Asio stackless coroutines, C++20 coroutines, and std::future. - Migrated from AsyncResult to new ErrorOr class which better emulates the proposed std::expected. - Session's asynchonous operations now return an ErrorOr result when passed a yield_context as the completion token, and will not throw if there was a runtime error. - Added Session::strand so that users may serialize access to the Session when using a thread pool. - Added Session overloads with the ThreadSafe tag type which can be called concurrently by multiple threads. - Added the SessionErrc::invalidState enumerator. - Renamed AnyExecutor to AnyIoExecutor. AnyExecutor is now deprecated. - Added AnyReusableHandler which type-erases a copyable multi-shot handler. - Added AnyCompletionHandler which is a Boost-ified version of the prototype asio::any_completion_handler. - Added AnyCompletionExecutor which is a Boost-ified version of the prototype asio::any_completion_executor. - Session and transports now extract a strand from the `Connector` passed by the user. - Moved corounpacker implementation to header directory root. - Added Realm::captureAbort. - Made config.hpp a public header. - Added DecodingErrc and DecodingCategory for deserialization errors not covered by jsoncons. - Session's setWarningHandler, setTraceHandler, setStateChangeHandler, and setChallengeHandler now take effect immediately even when connected. Those handlers are now executed via Session::userExecutor by default. - Boost.Asio cancellation slot support for Session::call. - Added withArgsTuple, convertToTuple and moveToTuple to Payload class. - Added the Deferment tag type (with 'deferment' constexpr variable) to more conveniently return a deferred Outcome from an RPC handler. - Renamed Cancellation to CallCancellation. Cancellation is now deprecated. - Renamed CancelMode to CallCancelMode. CancelMode is now deprecated. - Renamed Basic[Coro]<Event|Invocation>Unpacker to Simple[Coro]<Event|Invocation>Unpacker, with the former kept as deprecated aliases. - Renamed basic[Coro]<Event|Rpc> to simple[Coro]<Event|Rpc>, with the former kept as deprecated aliases. - Renamed the CppWAMP::coro-headers CMake target to CppWAMP::coro-usage, leaving the former as an alias. - Deprecated CoroSession, AsyncResult, error::Decode, and Outcome::deferred - Deprecated the Session::cancel overloads taking CallCancellation.
1 parent b1555e8 commit 29153f6

File tree

172 files changed

+13917
-4441
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

172 files changed

+13917
-4441
lines changed

CHANGELOG.md

+140
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,143 @@
1+
v0.10.0
2+
======
3+
Asio completion token support and thread-safe Session operations.
4+
5+
- All asynchronous operations in Session now accept a generic
6+
[completion token](https://www.boost.org/doc/libs/release/doc/html/boost_asio/overview/model/completion_tokens.html),
7+
which can either be a callback function, a `yield_context`, `use_awaitable`,
8+
or `use_future`.
9+
- C++20 coroutines now supported by Session.
10+
- Added examples using Asio stackless coroutines, C++20 coroutines, and
11+
std::future.
12+
- Migrated from `AsyncResult` to new `ErrorOr` class which better emulates
13+
the proposed `std::expected`.
14+
- `Session`'s asynchonous operations now return an `ErrorOr` result when passed
15+
a `yield_context` as the completion token, and will not throw if there was
16+
a runtime error. `ErrorOr::value` must be called to obtain the operation's
17+
actual result (or throw an exception if there was an error).
18+
- Added `Session::strand` so that users may serialize access to the `Session`
19+
when using a thread pool.
20+
- Added `Session` overloads with the `ThreadSafe` tag type which can be called
21+
concurrently by multiple threads. These overloads will be automatically
22+
dispatch operations via the `Session`'s execution strand.
23+
- Added the `SessionErrc::invalidState` enumerator which is now used to report
24+
errors when attempting to perform `Session` operations during an invalid
25+
session state.
26+
- Renamed `AnyExecutor` to `AnyIoExecutor` which aliases
27+
`boost::asio::any_io_executor`. AnyExecutor is now deprecated.
28+
- Added `AnyReusableHandler` which type-erases a copyable multi-shot handler,
29+
while storing the executor to which it is possibly bound.
30+
- Added `AnyCompletionHandler` which is a Boost-ified version of the prototype
31+
[asio::any_completion_handler]
32+
(https://github.com/chriskohlhoff/asio/issues/1100).
33+
- Added `AnyCompletionExecutor` which is a Boost-ified version of the prototype
34+
`asio::any_completion_executor`.
35+
- Session and transports now extract a
36+
[strand](https://www.boost.org/doc/libs/release/doc/html/boost_asio/overview/core/strands.html)
37+
from the `Connector` passed by the user.
38+
- Moved corounpacker implementation to header directory root.
39+
- Added `Realm::captureAbort`.
40+
- Made config.hpp a public header.
41+
- Added DecodingErrc and DecodingCategory for deserialization errors
42+
not covered by jsoncons.
43+
- `Session`'s `setWarningHandler`, `setTraceHandler`, `setStateChangeHandler`,
44+
and `setChallengeHandler` now take effect immediately even when connected.
45+
- `Session`'s handlers for `setWarningHandler`, `setTraceHandler`,
46+
`setStateChangeHandler`, and `setChallengeHandler` are now executed via
47+
`Session::userExecutor` by default.
48+
- Boost.Asio [cancellation slot]
49+
(https://www.boost.org/doc/libs/release/doc/html/boost_asio/overview/core/cancellation.html)
50+
support for `Session::call`.
51+
- Added `Rpc::withCancelMode` which specifies the cancel mode to use when
52+
triggered by Asio cancellation slots.
53+
- Added `withArgsTuple`, `convertToTuple` and `moveToTuple` to Payload class.
54+
- Added the `Deferment` tag type (with `deferment` constexpr variable`) to
55+
more conveniently return a deferred `Outcome` from an RPC handler.
56+
- Renamed `Cancellation` to `CallCancellation`. `Cancellation` is now a
57+
deprecated alias to ``CallCancellation`.
58+
- Renamed `CancelMode` to `CallCancelMode`. `CancelMode` is now a deprecated
59+
alias to `CallCancelMode`.
60+
- Renamed `Basic[Coro]<Event|Invocation>Unpacker` to
61+
`Simple[Coro]<Event|Invocation>Unpacker`, with the former kept as deprecated
62+
aliases.
63+
- Renamed `basic[Coro]<Event|Rpc>` to `simple[Coro]<Event|Rpc>`, with the
64+
former kept as deprecated aliases.
65+
- Renamed the CppWAMP::coro-headers CMake target to CppWAMP::coro-usage,
66+
leaving the former as an alias.
67+
- Deprecated `CoroSession` and `AsyncResult`.
68+
- Deprecated `error::Decode`
69+
- Deprecated the `Session::cancel` overloads taking `CallCancellation`.
70+
- Deprecated `Outcome::deferred`.
71+
72+
73+
### Breaking Changes
74+
75+
- Bumped Boost version requirements to 1.77 to support Asio cancellation slots.
76+
- Errors due to attempting to perform an asynchronous `Session` operation during
77+
an invalid state are now emitted via the `ErrorOr` passed to the handler,
78+
instead of throwing `error::Logic`. This is to avoid `error::Logic` exceptions
79+
being thrown due to race conditions outside the library user's control (for
80+
example, calling a remote procedure just as the peer terminates the session).
81+
This also avoids the complications involved in transporting exceptions to
82+
coroutines, as well as having two mechanisms for reporting errors from the
83+
same function.
84+
- `Session::authenticate` no longer throws if the session is not in the
85+
`SessionState::authenticating` state. Instead, the authentication is discarded
86+
and a warning is emitted.
87+
- `Session::publish(Pub)` no longer throws if the session is not in the
88+
`SessionState::established` state. Instead, the publicatioon is discarded
89+
and a warning is emitted.
90+
- `Session::cancel` no longer throws if the session is not in the
91+
`SessionState::established` state. Instead, the cancellation is discarded
92+
and a warning is emitted.
93+
- Numeric values of enumerators following `SesesionErrc::invalidState` have
94+
been bumped by one.
95+
- `Session::call` no longer returns the request ID. To obtain the request ID,
96+
use the new `Session::call` overload which takes a `CallChit` out
97+
parameter by reference.
98+
- The signature of `lookupWampErrorUri` has been changed so that it returns
99+
whether the corresponding error code was found.
100+
- Codec decoders now return a std::error_code instead of throwing an exception.
101+
- The `Transport` type requirement has been changed so that it provides a
102+
`boost::asio::strand` instead of a `boost::asio::any_executor`.
103+
104+
### Migration Guide
105+
106+
- Replace `AnyExecutor` with `AnyIoExecutor`.
107+
- Replace `AsyncResult` with `ErrorOr`.
108+
- Replace `AsyncResult::get` with `ErrorOr::value`.
109+
- Replace `AsyncResult::errorCode` with `ErrorOr::error`.
110+
- Replace `AsyncResult::setValue` with `ErrorOr::emplace`.
111+
- Replace `Basic[Coro]<Event|Invocation>Unpacker` with
112+
`Simple[Coro]<Event|Invocation>Unpacker`
113+
- Replace `basic[Coro]<Event|Rpc>` with `simple[Coro]<Event|Rpc>`
114+
- Replace `Cancellation` with `CallCancellation`
115+
- Replace `CancelMode` with `CallCancelMode`
116+
- Replace `CoroSession<>` with `Session`.
117+
- Replace `Outcome::deferred` with `deferment`.
118+
- Replace `#include <cppwamp/corosession.hpp>` with
119+
`#include <boost/asio/spawn.hpp>` and `#include <cppwamp/session.hpp>`.
120+
- Add `.value()` to `Session` methods taking a `yield_context` to preserve the
121+
old behavior where either the result value is returned upon success or an
122+
exception is thrown upon failure.
123+
- `std::error_code` pointers cannot be passed to the the consolidated `Session`
124+
class. Instead check the returned `ErrorOr` result via `operator bool` and
125+
`AsyncResult::error()`.
126+
- `Session::call` no longer returns the RPC request ID. Instead use the
127+
`Session::call` overload which takes a `CallChit` out parameter by reference.
128+
Alternatively, you may bind an Asio cancellation slot to the completion token.
129+
- Replace `Session::cancel(CallCancellation)` usages with
130+
`Session::cancel(CallChit)`.
131+
- If used directly, check the `std::error_code` returned by codec decoders
132+
instead of catching `error::Decode` exceptions.
133+
- Replace the `CppWAMP::coro-headers` CMake target with `CppWAMP::coro-usage`.
134+
135+
136+
v0.9.2
137+
======
138+
Fixed the non-compilation of examples.
139+
140+
1141
v0.9.1
2142
======
3143
Add -fPIC when building vendorized static Boost libraries.

CMakeLists.txt

+13-9
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
# This project defines one of more of the following targets, depending
1010
# on the how the CPPWAMP_OPT_X options are set:
1111
#
12-
# Target | Import alias | All | Description
13-
# ----------------------- | ------------------------ | --- | -----------
14-
# cppwamp-core | CppWAMP::core | Yes | Compiled libcppwamp-core library
15-
# cppwamp-core-headers | CppWAMP::core-headers | Yes | Header-only usage requirements
16-
# cppwamp-coro-headers | CppWAMP::coro-headers | Yes | Boost.Coroutine usage requirements
17-
# cppwamp-doc | <none> | No | Doxygen documentation
18-
# cppwamp-examples | <none> | No | Compiled example programs
19-
# cppwamp-test | <none> | No | Compiled test suite program
12+
# Target | Import alias | All | Description
13+
# -------------------- | --------------------- | --- | -----------
14+
# cppwamp-core | CppWAMP::core | Yes | Compiled libcppwamp-core library
15+
# cppwamp-core-headers | CppWAMP::core-headers | Yes | Header-only usage requirements
16+
# cppwamp-coro-usage | CppWAMP::coro-usage | Yes | Boost.Coroutine usage requirements
17+
# cppwamp-doc | <none> | No | Doxygen documentation
18+
# cppwamp-examples | <none> | No | Compiled example programs
19+
# cppwamp-test | <none> | No | Compiled test suite program
2020
#
2121
# 'All' means that the target (if enabled) is built as part of the 'all' target.
2222
# 'Usage requirements' means that the appropriate compiler flags will be set
@@ -38,7 +38,7 @@ cmake_minimum_required (VERSION 3.12)
3838
include_guard()
3939

4040
project(CppWAMP
41-
VERSION 0.9.1
41+
VERSION 0.10.0
4242
LANGUAGES CXX)
4343

4444
include(ProcessorCount)
@@ -84,6 +84,10 @@ option(CPPWAMP_OPT_WITH_CORO
8484
that depend on it"
8585
ON)
8686

87+
option(CPPWAMP_OPT_WITH_CORO20
88+
"Adds C++20 couroutine examples if examples are enabled"
89+
OFF)
90+
8791
option(CPPWAMP_OPT_WITH_DOCS
8892
"Creates a build target for generating documentation"
8993
${isTopLevel})

README.md

+25-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ C++11 client library for the [WAMP][wamp] protocol.
1010
- Roles: _Caller_, _Callee_, _Subscriber_, _Publisher_
1111
- Transports: TCP and Unix domain raw sockets
1212
- Serializations: JSON, MsgPack, and CBOR
13-
- Provides both callback and coroutine-based asynchronous APIs
13+
- Supports Boost.Asio completion tokens for callbacks, stackful coroutines,
14+
stackless couroutines, C++20 coroutines, and std::future.
1415
- Easy conversion between static and dynamic types
1516
- RPC and pub/sub event handlers can have static argument types
1617
- User-defined types can be registered and exchanged via RPC and pub-sub
@@ -21,7 +22,7 @@ C++11 client library for the [WAMP][wamp] protocol.
2122
**Dependencies**:
2223

2324
- [Boost.Asio][boost-asio] for raw socket transport
24-
(requires [Boost][boost] 1.74 or greater)
25+
(requires [Boost][boost] 1.77 or greater)
2526
- [jsoncons][jsoncons] for serialization
2627
- (optional) [Boost.Coroutine][boost-coroutine] and
2728
[Boost.Context][boost-context]
@@ -50,8 +51,8 @@ Tested Platforms
5051

5152
This library has been tested with:
5253

53-
- GCC x86_64-linux-gnu, versions 7.5 and 10.3
54-
- Clang x86_64-pc-linux-gnu, versions 6.0.1 and 12.0,
54+
- GCC x86_64-linux-gnu, version 10.3
55+
- Clang x86_64-pc-linux-gnu, version 12.0
5556

5657
<a name="advanced"></a>Supported Advanced Profile Features
5758
----------------------------------------------------------
@@ -70,19 +71,23 @@ This library has been tested with:
7071
Roadmap
7172
-------
7273

74+
### v0.11
75+
76+
- Polymorphic codecs and transports to prevent combinatorial explosion of
77+
explicit template instantiations when new codecs/transports are added.
78+
7379
### v1.0
7480

75-
- Make `wamp::Session` more thread-safe.
76-
- Remove `wamp::CoroSession` and make it so that `wamp::Session` can accept any
77-
completion token (`yield`, `use_future`, etc) supported by Boost.Asio.
81+
- Remove all deprecated types and functions.
82+
- Aim for API stability until v2.0.
7883

7984
### v1.1
8085

81-
- Add embedded router functionality
86+
- Embedded router functionality
8287

8388
### v1.2 (maybe)
8489

85-
- Add websocket support via Boost.Beast
90+
- Websocket support via Boost.Beast
8691

8792
### v2.0 (maybe)
8893

@@ -104,8 +109,8 @@ For reporting bugs or for suggesting enhancements, please use the GitHub
104109
[issues]: https://github.com/ecorm/cppwamp/issues
105110

106111

107-
Usage Examples Using Coroutines
108-
---------------------------------
112+
Usage Examples Using Stackful Coroutines
113+
----------------------------------------
109114

110115
_For a more comprehensive overview, check out the
111116
[Tutorials](https://ecorm.github.io/cppwamp/_tutorial.html) in the
@@ -517,6 +522,15 @@ your project or via your project's CMake scripts (for example by using
517522
`ExternalProject_add` or `FetchContent`).
518523

519524

525+
Bundled Open-Source Software
526+
----------------------------
527+
528+
This library bundles modified versions of `any_completion_handler` and
529+
`any_completion_executor` written by Christopher M. Kohlhoff,
530+
Copyright (c) 2003-2022, under the terms of the Boost Software License,
531+
Version 1.0 (http://www.boost.org/LICENSE_1_0.txt).
532+
533+
520534
License
521535
-------
522536

cmake/CppWAMPDependencies.cmake

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#-------------------------------------------------------------------------------
2-
# Copyright Butterfly Energy Systems 2022.
3-
# Distributed under the Boost Software License, Version 1.0.
4-
# (See accompanying file LICENSE_1_0.txt or copy at
5-
# http://www.boost.org/LICENSE_1_0.txt)
2+
# Copyright Butterfly Energy Systems 2022.
3+
# Distributed under the Boost Software License, Version 1.0.
4+
# https://www.boost.org/LICENSE_1_0.txt
65
#-------------------------------------------------------------------------------
76

87
include_guard()
@@ -11,7 +10,7 @@ include(FetchContent)
1110
set(FETCHCONTENT_QUIET OFF CACHE INTERNAL "")
1211

1312
# These minumum dependency versions must be made the same in CppWAMPConfig.cmake
14-
set(CPPWAMP_MINIMUM_BOOST_VERSION 1.74.0)
13+
set(CPPWAMP_MINIMUM_BOOST_VERSION 1.77.0)
1514

1615
set(CPPWAMP_VENDORIZED_BOOST_VERSION 1.79.0)
1716
set(CPPWAMP_VENDORIZED_BOOST_SHA256

cmake/FindCatch2.cmake

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#-------------------------------------------------------------------------------
2-
# Copyright Butterfly Energy Systems 2022.
3-
# Distributed under the Boost Software License, Version 1.0.
4-
# (See accompanying file LICENSE_1_0.txt or copy at
5-
# http://www.boost.org/LICENSE_1_0.txt)
2+
# Copyright Butterfly Energy Systems 2022.
3+
# Distributed under the Boost Software License, Version 1.0.
4+
# https://www.boost.org/LICENSE_1_0.txt
65
#-------------------------------------------------------------------------------
76

87
#[=======================================================================[.rst:

cmake/FindJsoncons.cmake

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#-------------------------------------------------------------------------------
2-
# Copyright Butterfly Energy Systems 2022.
3-
# Distributed under the Boost Software License, Version 1.0.
4-
# (See accompanying file LICENSE_1_0.txt or copy at
5-
# http://www.boost.org/LICENSE_1_0.txt)
2+
# Copyright Butterfly Energy Systems 2022.
3+
# Distributed under the Boost Software License, Version 1.0.
4+
# https://www.boost.org/LICENSE_1_0.txt
65
#-------------------------------------------------------------------------------
76

87
#[=======================================================================[.rst:

cppwamp-coro/CMakeLists.txt

+15-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
#-------------------------------------------------------------------------------
2-
# Copyright Butterfly Energy Systems 2022.
3-
# Distributed under the Boost Software License, Version 1.0.
4-
# (See accompanying file LICENSE_1_0.txt or copy at
5-
# http://www.boost.org/LICENSE_1_0.txt)
2+
# Copyright Butterfly Energy Systems 2022.
3+
# Distributed under the Boost Software License, Version 1.0.
4+
# https://www.boost.org/LICENSE_1_0.txt
65
#-------------------------------------------------------------------------------
76

8-
add_library(cppwamp-coro-headers INTERFACE)
9-
target_compile_features(cppwamp-coro-headers INTERFACE cxx_std_11)
10-
target_link_libraries(cppwamp-coro-headers
7+
# Empty interface library for conveniently adding usage requirements to
8+
# projects wanting to use stackful coroutines.
9+
add_library(cppwamp-coro-usage INTERFACE)
10+
target_compile_features(cppwamp-coro-usage INTERFACE cxx_std_11)
11+
target_link_libraries(cppwamp-coro-usage
1112
INTERFACE
12-
CppWAMP::core-headers
13+
CppWAMP::coro-usage
1314
"$<TARGET_NAME_IF_EXISTS:Boost::coroutine>")
14-
set_target_properties(cppwamp-coro-headers PROPERTIES EXPORT_NAME coro-headers)
15-
add_library(CppWAMP::coro-headers ALIAS cppwamp-coro-headers)
15+
set_target_properties(cppwamp-coro-usage PROPERTIES EXPORT_NAME coro-usage)
16+
add_library(CppWAMP::coro-usage ALIAS cppwamp-coro-usage)
17+
18+
# Deprecated aliases left for backward compatibility
19+
add_library(cppwamp-coro-headers ALIAS cppwamp-coro-usage)
20+
add_library(CppWAMP::coro-headers ALIAS cppwamp-coro-usage)

0 commit comments

Comments
 (0)