|
Boost : |
Subject: Re: [boost] [Boost-users] Networking TS + Beast, NEW Tutorials, Read this to learn std::net !!!
From: Vinnie Falco (vinnie.falco_at_[hidden])
Date: 2019-03-15 14:43:03
On Fri, Mar 15, 2019 at 7:19 AM Stian Zeljko Vrba <vrba_at_[hidden]> wrote:
> > I believe it is wrong to blame Asio for this.
>
> I disagree. Recently, I've been coding parallel, including networked &
> asynchronous, programs in C# and Java, and the experience has been a JOY. You
> get threads, executors, synchronization primitives, tasks, cancellation,
> monadic futures and concurrent (blocking and non-blocking) data structures
> out of the box with the platform, plus a myriad of extensions as libraries.
> As for executors, you don't need to be bothered with them unless you really
> want to for some reason.
>
If you were to compare POSIX or BSD sockets to C# and Java, you would say
exactly the same things. Asio (like Beast) is a low-level, portable
abstraction of I/O. You can BUILD "threads", "executors", "synchronization
primitives", "tasks", "cancellation", "monadic futures", and "concurrent
data structures" with it. Does this mean OS-level sockets are the wrong
abstraction?
Of course not. The reason C# seems "ahead" of C++ is two-fold:
1. WG21 goofed up by delaying networking
2. C# is not developed through the International Standards Process
These mistakes are being fixed though, and you will see library support in
C++ catch up by leaps and bounds. And when we finally get these things
(built on top of Asio/Networking TS, which has proven over and over to be
the correct low-level abstraction) it will be better than C#, Java, or Rust.
Compare the documentation for Vertx (vertx.io) or netty (both Java toolkits
> for writing asynchronous reactive programs) with that of asio.
>
Yes I agree, there is a lack of documentation and especially tutorials for
beginners (which I am trying to fix). This has nothing to do with whether
Asio is the right portable, low-level abstraction (it is) but the lack of
guidance from the author could lead you to believe incorrect things about
the lib.
Once I attempted to write an asio service, tried to understand the simple
> example from the documentation, and I gave up. I used a thread, blocking
> call and CancelSynchronousIO (and I consider myself fortunate to develop
> for Windows only that has it).
>
The documentation on services is particularly scant. There is no
explanation of what they are for, how to use them, best practices, or even
"Frequently Asked Questions." I was able to figure it out though, but I am
able to focus all of my time on it.
> Asio _is_ a relatively nice wrapper around socket and serial port APIs,
> but that's about it
>
Yes now you're getting close to an accurate description. More correct would
be to say that Asio provides robust abstractions of buffers, dynamic
buffers, synchronous I/O, and asynchronous I/O. Networking is a subset of
that (but not the only part, see signals and serial ports, and soon file
I/O).
> IMO. On the other hand, I could have written the same wrappers around
> native APIs in two days and not haul along what I consider the baggage of
> technical debt that is asio in the codebase.
>
There is no API technical debt. That is to say, that the interfaces are
modern and up-to-date. You could argue that particular implementations such
as Boost.Asio have extra code to provide C++03 compatibility, but this has
nothing to do with the soundness of the design. As these interfaces are
part of a TS, there will be implementations in gcc and clang appearing
shortly (if not already so). These will be written from scratch so there
will be no support for older C++.
> Conclusion, if any: many people just want/need thread per client and
> synchronous IO for simplicity, but until asio/networking TS provide for
> timeouts and cancellation of synchronous requests, it's a wrong tool for
> those people, me included.
>
If you define
struct sync_socket
{
net::io_context ioc_;
net::ip::tcp::socket_;
net::steady_timer timer_;
...
template<class Buffers>
std::size_t write_some (Buffers const& b);
};
You can easily implement timeouts in `write_some` thusly:
template<class Buffers>
std::size_t
sync_socket::
write_some (Buffers const& b, error_code& ec)
{
std::size_t n;
timer_.expires_after(seconds(30));
timer_.async_wait(
[&](error_code ec)
{
socket_.cancel(ec):
});
socket_.async_write_some(b,
[&](error_code ec_, std::size_t n_)
{
ec = ec_; n = n_;
});
ioc_.run();
return n;
}
Now, you can use `sync_socket` with all the usual sync write operations
like `net::write`, and get timeouts.
Thanks
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk