
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/