Boost logo

Boost :

Subject: [boost] Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!
From: Vinnie Falco (vinnie.falco_at_[hidden])
Date: 2019-03-14 16:48:23


Fellow C++, Boost, and WG21 Enthusiasts, lend me your ear!

I write to inform you about exciting developments in C++ networking.

First, a bit of background. Networking comes in three flavors:

* Networking TS <https://cplusplus.github.io/networking-ts/draft.pdf>
* Boost.Asio <https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio.html>
* Standalone Asio <https://github.com/chriskohlhoff/asio>

These three are for the most part identical, except that Asio flavors
have additional features like ssl::stream and signal_set which are not
in the TS, but will very likely appear in a future update or version.
We've had Asio for over a decade now, but there is a shortage of
experts. Some people believe this shortage is because Asio in
particular (and thus, Networking TS since they have identical
interfaces) is "difficult to use." I believe it is wrong to blame Asio
for this. Concurrent programs in general are hard to write. This is
applicable:

"Unfortunately, today's reality is that only thoughtful experts can
write explicitly concurrent programs that are correct and efficient.
This is because today's programming models for concurrency are subtle,
intricate, and fraught with pitfalls that easily (and frequently)
result in unforeseen races (i.e., program corruption) deadlocks (i.e.,
program lockup) and performance cliffs (e.g., priority inversion,
convoying, and sometimes complete loss of parallelism and/or even
worse performance than a single-threaded program). And even when a
correct and efficient concurrent program is written, it takes great
care to maintain — it's usually brittle and difficult to maintain
correctly because current programming models set a very high bar of
expertise required to reason reliably about the operation of
concurrent programs, so that apparently innocuous changes to a working
concurrent program can (and commonly do, in practice) render it
entirely or intermittently nonworking in unintended and unexpected
ways. Because getting it right and keeping it right is so difficult,
at many major software companies there is a veritable priesthood of
gurus who write and maintain the core concurrent code."
   - Herb Sutter, "The Trouble with Locks",
<http://www.drdobbs.com/cpp/the-trouble-with-locks/184401930>

Although this was written in 2005 it is still relevant today. It is
understandable that Asio will be the first target of anger and
frustration when writing concurrent programs, since it is on the
"front line" so to speak. There has also been a distinct shortage of
*good* tutorials and examples for Asio. Articles or blog posts which
teach you step by step, explaining everything, and giving example code
which demonstrates best practices.

Boost.Beast is my low-level HTTP/WebSocket library which builds on Boost.Asio:
<https://github.com/boostorg/beast>

In the original release of Beast, the documentation stated "prior
understanding of Boost.Asio is required." However, field experience
has shown that users ignore that requirement and attempt to write
complex, concurrent programs as their first-time introduction to both
Beast and Asio. Based on feedback from committee members, and to serve
users better, the scope of Beast has been enlarged to include
first-time users of networking. The upcoming Boost 1.70 release
reflects this new scope and I am excited to announce some very nice
things which you can access today.

First of all, Beast documentation and examples no longer use the
"boost::asio" namespace, they the namespace alias "net::". While this
is cosmetic, it reinforces the notion when inspecting code that it is
equally applicable to Boost.Asio, Asio, and Networking TS (identifiers
which are not in the TS, such as signal_set, are still qualified with
boost::asio).

A new documentation page explains the three flavors of networking:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io.html>

This is also explained in my 2018 CppCon presentation:

<https://youtu.be/7FQwAjELMek?t=444>

I have added a "Networking Refresher", a complete overview of
networking from soup to nuts. No prior knowledge or understanding of
networking is required, everything is explained in detail so if you
want to learn this is the place to start. I also kept it short, but it
is loaded with hyperlinks for further learning:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/asio_refresher.html>

There was a recent paper in Kona, P1269R0 ("Three Years with the
Networking TS") about difficulty of implementing timeouts. To address
this, Beast now has a stream class which implements configurable
timeouts for you, and callers no longer have to fiddle with timers
manually anymore. Everything "Just Works." It achieves the P1269R0
author's goal of having timeouts "built-in to asynchronous
operations", but in a way that fits in with the design of the TS:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/timeouts.html>

I feel that this `beast::basic_stream` serves as an existence proof
that the current design of Networking TS is sound - the TS offers a
flexible toolbox which lets you build your own framework the way that
you want it, without making odd choices for you. We are still
discovering ways of leveraging it to maximum use. The
beast::websocket::stream also has built-in timeouts, but they are
enhanced to support "idle pings" (keeping client connections alive)
and everything is fully configurable:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_websocket/timeouts.html>

All you need to do to get sensible, suggested websocket timeouts is
add one line of code after creating your stream:

        ws.set_option(websocket::stream_base::timeout::suggested(
beast::role_type::server));

To address the cumbersome boilerplate of writing composed operations
(specifically the need to propagate the associated allocator and
associated executor, and to avoid invoking the completion handler from
within the initiating function when the operation would complete
immediately) Beast adds two new utility base classes, with plentiful
documentation and examples throughout:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/writing_composed_operations.html>

There are two well-rounded examples which show you step by step how to
write these things in a safe way:

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/writing_composed_operations/echo.html>

<https://www.boost.org/doc/libs/master/libs/beast/doc/html/beast/using_io/writing_composed_operations/detect_ssl.html>

I have a big, new open source project which implements a server, that
uses the `system_context`, taking full advantage of native Windows and
Mac OS system-level execution context features. To support this use
case and industry feedback, the examples in Beast now default to being
always thread-safe. All examples use a "strand", and leverage P1322R0
("Networking TS enhancement to enable custom I/O executors"). Yes,
this paper which was approved in Kona, is now implemented in both
Boost.Beast, and Boost.Asio, including all of the Beast examples, so
if you pick up Boost 1.70 (or the master branches from github) you can
start playing with this as soon as you're done reading this message!!

<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html>

We have an active #beast channel in the C++ Slack
(https://slack.cpp.al) where experienced users can help, no question
is too small! I hope you will join me and the rest of the Beast and
Asio community in exploring what the very powerful Networking TS and
Asio libraries have to offer, and build something great together!

Regards

P.S. Don't forget to star the repository! <https://github.com/boostorg/beast>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk