Boost logo

Boost :

From: Don G (dongryphon_at_[hidden])
Date: 2005-04-13 22:02:49


Hi Caleb,

On 4/12/05, Don G wrote:

>> I've posted a zip with an HTML file and an HPP
>> file that describes an abstract way to interact
>> with the network.
>
> Overall it looks pretty nice.

Thanks. :) And thanks for taking the time to look at the proposal.

> A few observations:
> * port_t should be unsigned short, not unsigned int

That is, of course, true of TCP/IP :)

> * timeout constructors are inconsistent. One takes
> seconds + microseconds and one takes milliseconds,
> at least according to the names of the arguments.

Yeah, that was one of the adjustments I tried to make as I
boost-ified the code. The Windows way is millisecs, but Unix is
microsecs. To do microsecs, I think we would have to use uint64's.
That would be fine by me, but I wasn't sure how widely supported it
is. I know that for Solaris (SunPro), gcc, MSVC, CodeWarrior, uint64
is good. Of course, a timespec doesn't use uint64. La de da... :)

> * I wouldn't call the type you pass to the
> network::new_{local,broadcast,loopback,}_address
> method a "url". It isn't one.

But it is, at least from what the description in RFC 2396. You can
pass this:

  http://user:pswd@www.boost.org:8080/foo?x=42

and it would create an address object given that description. The
resolved (physical) address would be something like:

  http://user:pswd@66.35.250.210:8080/foo?x=42

> Perhaps "address_specifier" would be better? I can
> imagine some sort of "stream factory" class with
> pluggable protocols (e.g. http, https, ftp, etc) that
> would take fully qualified URLs to create new
> streams, but in this case you're dealing with at most
> a hostname and port.

Well, the semantics of such things quickly become non-streams. The
intention of the scheme ("http") is to establish a port by means of
name lookup. In the end, yes the URL is resolved to address/port. If
an HTTP library was built on top, it would do no transformation
before passing its URL to new_address(). Hence, the type "url".

> I'd contend that in general, an operating system supplied
> multiplexing facility will scale better than one that uses
> a thread to handle each connection.

Absolutely. The code I have in mind uses a thread pool and
connections are managed by as few a number of threads as necessary.
On Windows, each I/O thread can handle 64-ish connections. On Unix,
it is much higher. By default, I create one I/O thread per processor
and divvy up the connections.

> Without some sort of multiplexing facility, how do
> you know when a channel is ready for I/O? It seems that
> your proposal is to use a pool of threads to handle
> async/non-blocking operations, but I don't see any
> interfaces defined to control or manage these
> operations. Is that just TBD?

I have contemplated just how a user would want to interact with the
thread pool behind the scenes, but, it is ideally an issue of minimal
concern. Of course, for advanced users it could be something that
needs to be tweaked. In that sense, there is a TBD aspect. I just
have yet to see a good abstraction/mechanism for doing this.

> Clearly Windows select and WFMO are not as scalable
> as UNIX select/poll/etc,

In one sense WFMO could be better (it would not be constantly
repopulating fd_sets), but select or IOCP (I/O Completion Ports) are
it AFAIK. And IOCP is NT only (for those who care).

> but I'd contend that if one is writing a serious
> networking application for Windows, you are going to
> make use of *both* of these approaches (>1 instance
> of WFMO/select and thread pooling).
> In some cases, you may want to do this on UNIX too.

If one could do everything async, there should be no reason for
another thread pool. That would become important only if some
connection(s) had to do work that would prevent other connections
from progressing fairly (for example, by making blocking calls).

> I think the point I am trying to make is that there
> isn't necessarily one right answer. Pools of threads
> are good for some things, and I/O multiplexing
> facilities are good for some things. And in some
> cases, taken both together they are a good thing as
> well.

The threads in this pool are only doing I/O multiplexing, so I'm not
sure I understand your concern. The kind of thread pool in my
implementation is just to have roughly the minimum number of threads
compared to connections based on multiplexing limits. Another kind of
thread pool would be one/two per connection to handle blocking
activity. The blocking methods in the proposal could be used when
that was the right answer. Or did I miss your point here?

For best possible performance, one would want everything to be async
and handled directly in the I/O thread. That would eliminate
undesirable context switches. Since a given connection has all its
callbacks made from one thread (though that thread can change over
time), it wouldn't even need a lock as long as side effects were
confined.

I guess what I should do is write lots more in the HTML file :) There
are many areas left unclear that probably lead to confusion.

Again, thanks for the very thoughtful response!

Best regards,
Don

                
__________________________________
Do you Yahoo!?
Yahoo! Small Business - Try our new resources site!
http://smallbusiness.yahoo.com/resources/

                
__________________________________
Do you Yahoo!?
Yahoo! Small Business - Try our new resources site!
http://smallbusiness.yahoo.com/resources/


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