Created
April 16, 2020 20:27
-
-
Save vinniefalco/1587e03a851024308cfac07c96f227a3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
As requested, I am reproducing here my email to the author of P1269R0. | |
Apologies for the use of the second person singular. | |
--- | |
Hi, I'm the author of Boost.Beast: | |
<https://github.com/boostorg/beast/> | |
As such I am heavily invested in both Boost.Asio and Networking.TS. I | |
offer constructive comments on your paper. I use the general term Asio | |
to refer to Boost.Asio, stand-alone Asio, and Networking TS. For | |
reference, this is your paper that I reviewed: | |
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1269r0.html> | |
> 2. TLS, including native support for SChannel and SecureTransport (not available in ASIO) | |
You have to write your own stream wrapper, in the style of ssl::stream | |
which wraps a socket (as does beast::websocket::stream). But if your | |
algorithms are templated on stream concepts like AsyncReadStream and | |
AsyncWriteStream, then they will work with custom TLS wrappers right? | |
I don't see this as a limitation of Asio but rather a strength. Asio's | |
algorithms should similarly work with your TLS implementation (do | |
they?) | |
> 3.1 Synchronous I/O | |
I agree that synchronous I/O support is limited but I don't think it | |
was intended for those APIs to provide the same level of functionality | |
as the asynchronous APIs. They are supposed to be a thin abstraction. | |
The author has stated many times that timeouts are out of scope for | |
synchronous I/O. I find this position sensible. | |
> 3.2 I have strong reservations about the usability of any async framework in C++ built only on top of callbacks. | |
You might have a point about usability but I do not think usability is | |
or should be the primary goal of Asio. Instead, it should focus on | |
providing universal abstractions which allow for nothing in between | |
itself and the operating system. In other words it should be as low | |
level as possible while remaining portable. Usability is important but | |
not when it sacrifices flexibility or performance. | |
That said, the universal asynchronous model (async_result) mechanism | |
brilliantly allows primitives other than callbacks to be used such as | |
futures and coroutines (but you know this). Callbacks are the right | |
low-level abstraction over the operating system for asynchronous | |
operations. It should be the responsibility of network middleware | |
written on top to expose more usable interfaces, with no loss of | |
performance (other than any performance trade-offs inherent to the | |
usable interface). This is explained in great detail, in N3747 which | |
is an excellent read: | |
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf> | |
> 3.3 ...the intermixing of lifetime for socket operations and timers to time them out is difficult to manage... | |
Well that's putting it mildly...LOL. I am in agreement here. You are | |
right that adding timeouts to async operations would improve ease of | |
use but it would also result in an abstraction that is less flexible. | |
Adding those timeouts would take important decisions about their | |
implementation away from the user. | |
Anyway, I have developed a TCP/IP stream wrapper which provides | |
exactly the feature you want, which is to have an automatic timeout | |
(currently implemented only for reads). This is accomplished in | |
async_read_some which will return a custom error code if no activity | |
occurs. The idea is to be able to just drop it right in, so that any | |
templated stream algorithm will work with it. You can see that code | |
here: | |
<https://github.com/vinniefalco/beast/blob/timeout/include/boost/beast/experimental/core/timed_socket.hpp#L35> | |
At some point I will refine it and make it part of Beast's | |
experimental interfaces. | |
With such an implementation, you could combine it with coroutines or | |
futures (which already work with Asio and therefore Beast) and get | |
something which allows you to write code in the synchronous style but | |
that supports timeouts. I believe this addresses your use-case. | |
> 3.4.1 Relationship with the Executors TS | |
Addressed in this paper: | |
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0958r0.html> | |
> 3.4.2 Over Generalization | |
Addressed in this paper: | |
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html> | |
> 4.1 Core of the critique | |
> Without the addition of futures or coroutines, callbacks compose poorly | |
I couldn't disagree more. Composition is one of the greatest strengths | |
of Asio's abstractions. In fact I dedicate two tutorials on how to | |
write them in the Beast documentation: | |
<https://www.boost.org/doc/libs/1_68_0/libs/beast/doc/html/beast/using_io/writing_composed_operations.html> | |
<https://www.boost.org/doc/libs/1_68_0/libs/beast/doc/html/beast/using_io/example_detect_ssl.html> | |
Almost all of your criticisms of Asio can be addressed simply by | |
gaining proficiency at understanding and writing correct asynchronous | |
Asio code. Yes I agree that the domain has a certain level of | |
complexity that cannot be decomposed but Asio's abstractions are in my | |
opinion, mostly correct. | |
Regards |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment