
Hi Cliff, --- Cliff Green <cliffg@codewrangler.net> wrote:
Exactly - in my own (soon upcoming, hopefully) Asio review I mention that I see the Asio demuxer as a general asynch I/O demuxer (which is also what I understand Chris intends). E.g. the demuxer could be used for file I/O, and in that case there should be interfaces (eventually) to use Boost.Filesystem with the demuxer. Of course the (current) synchronous Filesystem interfaces will not go away. The same could be said for many other (currently synchronous only) libraries. I don't think Sockets should be an exception - i.e. Sockets can only be used with a demuxer, but Filesystem can be used without.
We can argue about the most efficient and scalable way to design high-performance network applications, but there will always be use cases for small, simple, synchronous socket libraries. As long as there is well-documented and easy paths to the higher-performance asynchronous interfaces, I see real advantages to layering it this way.
Since you mention files, it's worth remembering that the synchronous abstraction for files in the standard library is iostreams. I think it is reasonable to include a socket iostream class that is layered on top of asio and hides all of the asynchronous stuff away, simply because iostreams are a part of the standard library that most people are already familiar and comfortable with. I now intend to add one (i.e. turn the current iostreams example into part of the library), although I'm not yet quite sure what the programming interface should be (and whether it would require another review?). However, we must be careful here. Sockets are not files. With files you can get away with synchronous operations in all sorts of places because they are usually fast. For example, you can perform file I/O in a user interface thread and the user is unlikely to be aware of any delay. Socket operations, on the other hand, can involve delays many orders of magnitude larger. Networks introduce latency. Socket read operations can continue indefinitely with no data arriving on the socket. These issues are inherent in network programming. No synchronous interface can hide them away. In all but the simplest applications, it is a matter of when, not if, they will need to be addressed. As I have mentioned elsewhere, I believe that it is when programmers reach this point that exposure only to synchronous interfaces, and no awareness of asynchronous, can limit their consideration of appropriate designs. Therefore I also believe it will be counterproductive to offer a lower-level synchronous-only API, a "false economy" if you like. Asynchronous I/O is not only applicable for high performance and scalability. The big advantage for applications of any size is that it offers concurrency without threading. In my experience, multithreading is more error prone than asynchronous I/O. So to reiterate, I think the appropriate way to provide a synchronous sockets API is an iostreams-based interface, and as suggested I intend to include one in asio. When developers start to find the iostreams interface too limiting, I feel that is when they are probably ready to be introduced to asynchronous I/O. Cheers, Chris