
On 8/18/05, Christopher Kohlhoff <chris@kohlhoff.com> wrote:
- What people think of the relative importance of the items. For example, what would be required for an initial implementation vs what could or should be left until a later revision.
Reading back through my comments (below), I don't think any of the Missing Features is a show-stopper. I'd say rationalizing interfaces for inclusion in Boost (e.g. perhaps using boost::xtime instead of asio::time, etc) and expanding the documentation and example code would be the top priority. All IMHO of course.
- Whether the proposed changes are of any value.
Yes they all have merit.
- Any other things that should be on the list.
What's Missing ==============
* Asynchronous DNS operations. I think it would be reasonable to say that any operation that can block should have an asynchronous equivalent. Should these operations be cancellable (not necessarily portably implementable anyway)?
The async DNS calls would be a nice-to-have feature, and I'd give that a Medium priority. Making the operations cancel-able would be Low.
* IPv6 support. I have no experience with IPv6, so it would be great if someone with experience could help out with the design here.
Another nice to have, but the way in which you have placed the existing IPv4 code into its own namespace leads me to believe this can be added later with little pain. For some it may be a top priority, but I'd give this a Low priority personally.
* Asynchronous socket close. In certain circumstances closing a socket can block, so it would be reasonable to expect an asynchronous close operation.
Would this be just a matter of adding an asio::async_close free function? Not sure how you implement this on various platforms, but it seems like a Low to Medium priority.
* Scatter-gather operations (sendv and recvv).
I'd give this Low priority.
* The BSD socket functions sendmsg/recvmsg (which I believe are necessary to support protocols such as SCTP).
Again, Low.
* SSL/TLS and DTLS support. This would require an external library, and how does that fit in with boost?
You can probably look at the ICU support in Boost.Regex and the Gzip/Bzip2 support in Iostreams as examples. The extra libraries enable additional functionality, but without them the libraries still function. Low to Medium priority.
* Other protocols (PF_UNIX, ...)?
Low to Medium.
* Some type of integration (or support for) a higher-level iostreams-based socket library.
It ought to be quite simple to provide this using Boost.Iostreams. Low priority.
* More examples. * Documentation on design and rationale.
These two taken together merit High priority.
What Should Be Included and What Shouldn't ==========================================
* Obviously asio::thread should not be part of a boost proposal, since that functionality is already covered by Boost.Thread.
I do very much enjoy the 100% header implementation you have now, but having to link to a library would not be a show-stopper. It does seem a bit of a shame that a number of Boost libraries that are thread-safe/aware (SharedPtr, Pool, Regex) have provided their own e.g. mutex classes instead of using the ones in Boost.Threads. This is not a value judgement, just an observation.
* The asio::time class should probably not be included, and wherever it's used replaced by Boost.Date-Time.
I think boost::xtime is the right choice there.
Naming and Structure ====================
* The use of the word "Stream" can be confusing because its existing association in C++ with iostreams. Can anyone suggest an alternative?
I personally think that "stream sockets" are (or should be) a well-known term and that to call them something else would be more confusing.
* Should stream_socket and dgram_socket be merged into a single socket class? There other types of sockets (e.g. sequenced packet) that would require additional classes if the current approach is retained. This would not be required if the BSD socket APIs were covered by a single class. Alternatively, should additional classes be added for the other socket types?
This is an interesting point that has arisen before. Do the different types of sockets warrant different classes? I'm not sure I have the Design Fu to answer this one well.
* The current separate socket_connector implementation does not correspond to an OS resource, unlike socket_acceptor. This can be problematic, e.g. it prevents a Windows implementation using ConnectEx, and doesn't allow you to set socket options before the connection is established. Therefore I propose adding connect and async_connect operations to socket classes. Should the separate socket_connector be retained?
Seems like a sensible change, and once done I don't see the value in socket_connector.
* In designing asio I considered that people may want to customise the demultiplexing strategy associated with each resource. For example the basic_stream_socket template looks like:
template <typename Service> class basic_stream_socket;
where Service is a "facet" of the demuxer that provides demultiplexing facilities for the socket. The typedef for stream_socket specifies the Service type based on the target platform.
However in practice I don't believe this level of customisation is required (to the best of my knowledge no existing asio user customises it), particularly if asio uses the "best" demultiplexing mechanism for each platform. Or another way of looking at it: developers who need this level of control might not use a general purpose networking library anyway.
It also prevents runtime-pluggable demuxing facilities, which might be useful on some platforms. For example, what if I compile my application on a Linux 2.6 machine that supports epoll, but I want to run it on a 2.4 machine that doesn't support this API? Being able to select the best mechanism at *runtime* would be very handy here. This is analagous to the Reactor implementation in ACE, which is pluggable at runtime.
An alternative approach would to have the only template parameter be an allocator (since there is often memory allocation associated with asynchronous operations). For example:
template <typename Allocator> class basic_demuxer;
template <typename Allocator> class basic_stream_socket;
where a stream_socket can only be used with a demuxer that has the same allocator type. The typedefs for demuxer and stream_socket would just use the default allocator.
This seems to make more sense to me than making the socket type dependent on the demuxing strategy. Thanks again for such a nice library! -- Caleb Epstein caleb dot epstein at gmail dot com