Boost logo

Boost :

From: Arkadiy Vertleyb (vertleyb_at_[hidden])
Date: 2005-12-19 22:28:06


"Christopher Kohlhoff" <chris_at_[hidden]> wrote

> --- Arkadiy Vertleyb <vertleyb_at_[hidden]> wrote:
> > Could you provide some (high-level) justification of why it is
> > beneficial to have a socket dependency upon a demuxer?
> >
> > Maybe I am missing something, but IMO such a dependency is
> > unnatural even for asynchronous IO.
>
> This has not come up in the discussion thus far, but the
> dependency on the demuxer is required to enable an efficient and
> portable implementation of asynchronous I/O. This is one of the
> primary goals of asio. The asio interface has been designed to
> reflect efficient asynchronous I/O mechanisms across major
> operating systems.
>
> Let's take the specific case of Windows, where asynchronous I/O
> is implemented using I/O completion ports. Once a socket is
> associated with an I/O completion port it cannot be
> disassociated.
>
> In asio, the demuxer represents the I/O completion port.
> The asio interface enforces this association by constructing the
> socket with its associated demuxer/IO-completion-port.
>
> >From the point of view of the library user, any asynchronous
> operations started on the socket will have the completion
> handler delivered through the associated demuxer (as it is with
> I/O completion ports).
>
> Separating the asynchronous I/O operations from the socket class
> would no longer enforce this requirement at compile time.
> (That's even leaving aside questions about where the operation
> logically belongs.)

Understand and agreed. For async IO, socket doesn't seem to make a sence
without a demuxer. Passing the demuxer to the socket constructor in this
case makes perfect sense.

> > Hiding it behind default parameter, singleton,
> > etc., just masks what I believe is a design problem.
> >
> > If you absolutely believe this dependency is necessary for
> > async IO, having two separate classes, such as sync_socket and
> > async_socket would be much cleaner. But again, I can't see
> > what justifies such a dependency even for async IO.
>
> So the question is really whether there should be separate sync
> and async socket classes, versus a combined class as there is
> now. I believe that, on balance, separate classes would be
> harmful. Let's reiterate some of the points:
>
> - Synchronous and asynchronous operations are essentially the
> same, in that they perform the same operation and aim to
> fulfil the same contract. How they differ is simply that one
> blocks the current thread, whereas the other executes in a
> background logical thread and tells you when it is complete. I
> want there to be a clear mapping from one to the other.

That should not be difficult to achieve with derivation or some sort of
policy. Looks like async_socket might be derived from sync_socket (or
contain it).

> - Separate classes reinforces the notion that synchronous
> operations are somehow more useful for the ordinary
> programmer, and that asynchronous is hard and best left in the
> realm of the networking guru. I do not believe that
> asynchronicity is difficult to use or understand, it is simply
> that programmers often approach sockets with preconceived
> ideas of how an API should behave. But I do believe that
> separating the classes will continue the lack of awareness of
> asynchronicity as an option, leading to the needless use of
> inferior designs.

I don't agree that separate classes reinforce any notion. They just clearly
state that there are two different ways of doing things. And I don't
believe forcing people to use a demuxer without the need is a right way to
raise awareness...

> - The greater number of classes and options will increase the
> size of the library's interface.

One of the fundamental OO design principles states that clients should not
depend on what they don't use (Interface segregation principle).

> - I have demonstrated that there is a use case for mixed-mode
> applications. Predominantly synchronous designs can benefit
> from localised asynchronicity. Asynchronous designs can be
> simplified by selective use of synchronous calls.

So one would use async sockets in this case.

> - A line of reasoning has been presented which says that,
> because files already have a synchronous-only interface and
> could be given an asynchronous interface, sockets should also
> have a synchronous-only interface. However, sockets are
> inherently different to files due to the long timescales
> involved in many operations. Developers will look for some
> form of concurrency to address this, and I believe
> asynchronicity *should* be promoted over threads as a
> solution.
>
> It is worth noting that even .NET combines the sync and async
> socket operations on a single interface.
>
> I do find that there is a compelling case for a synchronous-only
> interface to sockets at the iostreams level. But that is because
> of the established use and wide applicability of iostreams, not
> because it is synchronous.
>
> So let me turn the question around. Why must there be a
> low-level synchronous-only interface at all? What benefits
> will it bring? What use cases do you have that cannot be met by
> a combined interface or an iostream interface?

I don't like the the combined interface because it doesn't satisfy the
interface segregation principle. Also I don't like when things have to be
specified that are not used.

iostream might be alright, but it makes things kind of asynchronous (in the
other sence of this word). Also you don't win anything -- you will have two
interfaces, the same amount you would have with sync_ and async_socket.

Regards,
Arkadiy


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