Boost logo

Boost :

From: Don G (dongryphon_at_[hidden])
Date: 2005-04-15 08:32:19


Hi Maxim,

Don G wrote:
>>> None of the calls should block.
>>
>> But the sync ones _must_ block. All of the logical
>> operations can be invoked sync/async. The non-blocking
>> approach, from my definition<g>,
[snip]
>> I think this has a place for I/O, but not for connect/
>> accept. These are binary steps whereas I/O can be
>> viewed as a continuous march to completion.

> Consider a proxy server for example. It accept a
> connection and then connects to destination. If accept/
> connect block, it won't be possible to handle in one
> thread multiple clients. But AFAIK performance proxy
> servers are actually single threaded.

They would use async, not blocking calls (in the proposal I made). I
reread my post and it sounds as if I am saying that single threaded
servers cannot be high performance. Of course, they can. I still
believe a multi-threaded server will be higher performance.

> One of my previous project was a soft realtime VoIP
> softswitch. It has only one thread of execution and is
> capable of handling 1000+ simultaneous calls (2000-
> 4000 sockets). It scales up by just starting additional
> processes on the same box, no recompilation needed, no
> locking, simple and immensely powerful.

I knew we had a definition problem: handling 1000+ simultaneous
connections would not be something I would label as "simple"! ;)

I have multiple thoughts here. First, I think the only difference our
two approaches would yield is that with my approach, one might need
locks. I did say "might". No lock is needed if the object managing a
connection is basically autonomous, changing only its state is
response to I/O completion or requesting further I/O, and/or creating
new connections. While the internals of the network implementation
are threaded, on a per-connection basis, callbacks are single
threaded.

Secondly, I don't think a queue of boost::function<> would be found
by the profiler as a performance bottle-neck (though I haven't looked
inside it at all). This is the approach I have taken to handle lots
of async calls from one thread. Not 1000+, but I'm not sure the
hardware and OS you used.

>>> I hope this won't happen. There are several I/O
>>> patterns in use out there.
>>
>> But, honestly, how many do we need?
>
> This is the main questions. I doubt we can ever
> answer this. So, I see no reason in dictating a
> style.

There are some reasons for picking a small number of styles:

1. Simpler for a user to understand
2. Simpler to document
3. Simpler to test
4. Simpler to write higher level libs (they should have
   have symmetric styles for their users)
5. Not all styles are portable (w/o undue complexity)
6. Simpler to implement :)

I can only think of one advantage of multiple styles: familiarity
with existing practice. These practices may or may not be "good"<g>
but they are familiar. It is my contention that by supporting too
many "familiar idioms" we jeopardize all of the above.

>>> You don't just send bytes, rather you execute
>>> protocols. Sockets have the right implementation
>>> level and complexity to build *efficient*
>>> protocols upon.
>>
>> How hard should it be to write a protocol? How
>> reusable should it be?
>
> Try implementing H.323 family. (Although it dies,
> but it does not die as fast as I want it to).

Fortunately, I have not had to tackle H.323. :) See my above list for
the intent of this question.

> Yes, I'm familiar with and used OpenSSL a lot. It
> exposes a good C object model. Would you like to
> make it expose C++ interface? I doubt that it makes
> any sense, sinse IMO OpenSSL interface is good
> enough. The same point of view I have for sockets.

Yes, I would like a C++ interface. In fact, it would be basically as
I proposed: net::stream. I realize that there are many other aspects
to OpenSSL beyond streaming. And, of course, I would like a C++
interface to all of it. Sadly, the openssl folks aren't writing it
and I have no desire to do so. If there were an openssl/C++, I would
switch (all other things being equal).

>> So, let's say we have an HTTP library. How do
>> we wait for responses? Expose the socket(s) it
>> uses?
>
> No.
>
> At application level we operate on PDUs (which
> are HTTP messages here). No sockets exposed. All
> the socket manipulation is done inside HTTP
> protocol library.
>
> Here I attached an async protocol layer
> abstractions I've been using in my current
> project.

>From the code you posted, it appears that you use callbacks using
abstract bases not boost::function<> (which is fine and it does avoid
any possibility of deep copy under the covers).

So, say I have lots of HTTP connections to process. Would I be
getting callbacks for completion? If so, why should this be
fundamentally different than the layer below? Also, how does HTTP
client code differ from HTTPS client code? One must interact with the
SSL library and another with sockets...

Best,
Don

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


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