|
| 1 | +| | [Docs](https://develop.beast2.cpp.al/) | [GitHub Actions](https://github.com/) | [Drone](https://drone.io/) | [Codecov](https://codecov.io) | |
| 2 | +|:--|:--|:--|:--|:--| |
| 3 | +| [`master`](https://github.com/cppalliance/beast2/tree/master) | [](https://master.beast2.cpp.al/) | [](https://github.com/cppalliance/beast2/actions/workflows/ci.yml?query=branch%3Amaster) | [](https://drone.cpp.al/cppalliance/beast2/branches) | [](https://app.codecov.io/gh/cppalliance/beast2/tree/master) | |
| 4 | +| [`develop`](https://github.com/cppalliance/beast2/tree/develop) | [](https://develop.beast2.cpp.al/) | [](https://github.com/cppalliance/beast2/actions/workflows/ci.yml?query=branch%3Adevelop) | [](https://drone.cpp.al/cppalliance/beast2/branches) | [](https://app.codecov.io/gh/cppalliance/beast2/tree/develop) | |
| 5 | + |
| 6 | +# Beast2 |
| 7 | + |
| 8 | +Coroutines-Only Networking for Modern C++ |
| 9 | + |
| 10 | +## The Problem |
| 11 | + |
| 12 | +Boost.Asio transformed C++ networking. It also burdened every call site with templates, platform headers, and implementation machinery, yet its quarter century of field experience produced capable, working abstractions. |
| 13 | + |
| 14 | +The C++26 `std::execution` API offers a different model, designed to support heterogenous computing. Our research indicates it optimizes for the wrong constraints: TCP servers don't run on GPUs. Networking demands zero-allocation steady-state, type erasure without indirection, and ABI stability across (e.g.) SSL implementations. C++26 delivers things that networking doesn't need, and none of the things that networking does need. |
| 15 | + |
| 16 | +## The Design Principle |
| 17 | + |
| 18 | +Peter Dimov insists we begin with what developers actually write: |
| 19 | + |
| 20 | +```cpp |
| 21 | +auto [ec, n] = co_await sock.read_some( buf ); |
| 22 | +``` |
| 23 | + |
| 24 | +One line. No platform headers. No completion handlers. Just coroutines. This simplicity drives every architectural decision: |
| 25 | + |
| 26 | +- **Clean call sites** — no platform or implementation headers leak through |
| 27 | +- **Extensible concepts** — user-defined buffer sequences and executors; stream wrappers without templates |
| 28 | +- **Zero-alloc steady state** — no coroutine frame allocations in hot paths |
| 29 | +- **Minimal template exposure** — implementation details stay in the translation unit |
| 30 | +- **Allocation-free type erasure** — user types preserved without small buffers or malloc |
| 31 | +- **Fine-grained execution control** — strands, processor affinity, priority scheduling |
| 32 | + |
| 33 | +Boost.Asio gave us the field experience. These design choices reflect what we learned. |
| 34 | + |
| 35 | +## The Library Family |
| 36 | + |
| 37 | +Beast2 is an umbrella term for a family of libraries that work together: |
| 38 | + |
| 39 | +**Boost.Capy** — The execution foundation, optimized for async I/O. Core types: `task<T>`, `thread_pool`, `strand`, `coro_lock`. Tasks propagate executor context through `await_suspend` automatically, guaranteeing correct executor affinity. Provides allocation-free type erasure, frame allocators for coroutine memory, automatic stop token propagation, and buffer algorithms. **This should go into the C++ Standard Library**. |
| 40 | + |
| 41 | +**Boost.Corosio** — Coroutine-only portable networking and I/O that wrap per-platform implementations. Every operation returns an awaitable; no callbacks. Core types: `socket`, `acceptor`, `resolver`, `strand`, `io_context`, SSL stream wrappers (WolfSSL and OpenSSL), non-templated streams, scatter/gather buffers, native `std::stop_token` cancellation. |
| 42 | + |
| 43 | +**Boost.Http** — Sans-I/O HTTP/1.1 with strict RFC compliance. Protocol logic isolated from I/O for testability and framework independence. Core types: `request`, `response`, `parser`, `serializer`, `router`. Non-templated containers, memory-bounded parsers, body streaming, Express.js-style routing, automatic gzip/deflate/brotli application, and an extensive collection of HTTP "middleware" algorithms such as multipart/form processing, cookie management, bcrypt, and more. |
| 44 | + |
| 45 | +**Boost.Websocket** — WebSocket algorithms and structures. Same philosophy. |
| 46 | + |
| 47 | +**Boost.Beast2** — High-level HTTP and WebSocket servers. Express.js-style routing, multithreaded, idiomatic C++. |
| 48 | + |
| 49 | +**Boost.Burl** — High-level HTTP client. The features of curl, the ergonomics of coroutines, and the design sensibility of Python Requests. |
| 50 | + |
| 51 | +Each of these libraries is built for direct use. Boost.Capy can be standardized without risky socket or SSL decisions. Combine as needed. |
| 52 | + |
| 53 | +## Technical Advantages |
| 54 | + |
| 55 | +Beast2 continues the Boost tradition of innovation through working code. |
| 56 | + |
| 57 | +### Zero-Allocation Steady-State |
| 58 | + |
| 59 | +`capy::task` coroutine frames reuse memory (delete before dispatch). Type erasure is achieved without small-buffer optimizations or malloc. User types are preserved through the abstraction boundary. Key insight: |
| 60 | + |
| 61 | +> _The coroutine frame allocation we cannot avoid, pays for all the type-erasure we need._ |
| 62 | +
|
| 63 | +### Templates Where They Matter |
| 64 | + |
| 65 | +Boost.Asio: |
| 66 | + |
| 67 | +```cpp |
| 68 | +template< class AsyncStream, class CompletionToken > |
| 69 | +auto do_io( AsyncStream&, CompletionToken&& ); |
| 70 | +``` |
| 71 | +
|
| 72 | +Boost.Corosio: |
| 73 | +
|
| 74 | +```cpp |
| 75 | +auto do_io( capy::any_stream& ); // returns awaitable |
| 76 | +``` |
| 77 | + |
| 78 | +No loss of generality. Buffer sequences and executors remain concept-driven. Stream wrappers require no templates. The drawbacks of `std::execution` can be seen in a single line: |
| 79 | + |
| 80 | +```cpp |
| 81 | +connect( sndr, rcvr ); // C++26, unavoidable templates |
| 82 | +``` |
| 83 | +
|
| 84 | +Here, the compiler must see all the types (or perform expensive type-erasure, which is inconvenient at this call site and uncompetitive). No encapsulation. Long compile times. ABI fragility. Unfriendly to network programs. |
| 85 | +
|
| 86 | +### ABI Stability by Design |
| 87 | +
|
| 88 | +Boost.Asio: |
| 89 | +
|
| 90 | +```cpp |
| 91 | +template< class AsyncStream > |
| 92 | +class ssl_stream |
| 93 | +{ |
| 94 | + AsyncStream stream_; |
| 95 | + ... |
| 96 | +``` |
| 97 | + |
| 98 | +Boost.Corosio: |
| 99 | + |
| 100 | +```cpp |
| 101 | +class wolfssl_stream : public tls_stream |
| 102 | +{ |
| 103 | + io_stream& wrapped_stream_; |
| 104 | + ... |
| 105 | +``` |
| 106 | +
|
| 107 | +Stream algorithms see `tls_stream&` not `wolfssl_stream&` and can be written as ordinary functions (non-templates). Link your HTTP library against Corosio and WolfSSL. Relink against OpenSSL. No recompilation. SSL implementation becomes a runtime decision with zero ABI consequence. Have both in the same executable if you want (maybe useful for researchers). |
| 108 | +
|
| 109 | +### No Configuration Macros |
| 110 | +
|
| 111 | +There is only one configuration of the library: |
| 112 | +
|
| 113 | +Boost.Asio: |
| 114 | +
|
| 115 | +```cpp |
| 116 | +#define BOOST_ASIO_NO_SCHEDULER_MUTEX 1 |
| 117 | +
|
| 118 | +{ |
| 119 | + asio::io_context ioc; |
| 120 | +} |
| 121 | +``` |
| 122 | + |
| 123 | +Boost.Corosio: |
| 124 | + |
| 125 | +```cpp |
| 126 | +{ |
| 127 | + corosio::unsafe_io_context uioc; // no macro needed |
| 128 | + |
| 129 | + corosio::io_context ioc; // use one or both, linker removes whats not used |
| 130 | +} |
| 131 | +``` |
| 132 | + |
| 133 | +One library. One object file. Runtime configuration. |
| 134 | + |
| 135 | +### Implementation Hiding |
| 136 | + |
| 137 | +No platform headers at call sites. No implementation structures in user code. Translation-unit isolation by default. ABI is stable by design, and thus if adopted in the standard can be evolved rather than freezing. |
| 138 | + |
| 139 | +## Boost.Beast2 |
| 140 | + |
| 141 | +Unlike its predecessor, Beast2 is _full-featured_ and **high-level**. Everything is in scope: |
| 142 | + |
| 143 | +```cpp |
| 144 | +app.use( "/", serve_static( "C:\\Users\\Vinnie\\my-website" ) ); |
| 145 | +``` |
| 146 | + |
| 147 | +Express.js patterns. Multithreaded execution. C++ performance. |
| 148 | + |
| 149 | +## Summary |
| 150 | + |
| 151 | +The Beast2 family of libraries responds to the pain points related by users and delivers everything they want. It demonstrates through working code what modern C++ networking requires: coroutine-native design, fast compilation without loss of generality, ABI stability across implementations, and good performance, while preserving every capability that made Boost.Asio great. |
| 152 | + |
| 153 | +This is the future of C++ networking. |
| 154 | + |
| 155 | +--- |
| 156 | + |
| 157 | +_Boost.Beast2 is under active development. API subject to change._ |
0 commit comments