On Linux, FreeBSD and Solaris (at least), even with the most recent nonblocking 
kernel facilities, it is still faster to accept new TCP connections in a 
blocking fashion via thread pool. FWIW.

--
Theo Schlossnagle (mobile)
http://omniti.com/is/theo-schlossnagle

On Jan 23, 2012, at 1:19 PM, John Plevyak <jplev...@acm.org> wrote:

> I think Leif has it right about the use cases and meaning of
> frequent_accept.   Given how much has changed kernel-wise since that code
> was originally written, it isn't clear how much we save by limiting some
> accepts to a single thread non-blocking (i.e. epoll() makes the marginal
> cost of another fd small, and modern OSes handle many more threads
> efficiently than they used to).
> 
> The key question is "why is the test failing", and AFAICT it looks like
> NetAccept::init_accept() isn't doing:
> 
>    PollDescriptor *pd = get_PollDescriptor(t);
>    if (a->ep.start(pd, a, EVENTIO_READ) < 0)
> 
> link in init_accept_per_thread().  So it isn't clear to me why it would get
> called ever.
> 
> It just looks like this code needs to be simplified and cleaned up a bit.
> There is a lot of commented out code and convoluted paths and the code is
> split between NetAccept and UnixNetProcessor which further complicates
> things.  There are too many different paths which do largely the same thing
> under different circumstances, and yes, we might loose a few cycles by
> factoring the code better, but it would be much more maintainable, stable
> and (hopefully) bug free.
> 
> The way the code is now, we tend to have the main entry points for a
> processor in the XXXXProcessor.cc file and then some code for each point in
> another XXXFoo file.  This tends to split up the code which is confusing.
> Perhaps for main entry point Foo we should just have all the code in
> XXXFoo, in this case UnixAccept.cc for example.
> 
> I'll see if I can break away some time.
> 
> john
> 
> On Mon, Jan 23, 2012 at 7:50 AM, Leif Hedstrom <zw...@apache.org> wrote:
> 
>> On 1/23/12 7:57 AM, Alan M. Carroll wrote:
>> 
>>> Sunday, January 22, 2012, 10:20:58 PM, you wrote:
>>> 
>>>      if (frequent_accept) { // true
>>>> 
>>> I read that as "checking to see if frequent_accept is true".
>>> 
>> 
>> Right, and it used to be always true. And you are suggesting to change it
>> to "false", no ?
>> 
>> 
>> 
>>> What's semi confusing is that the declaration of accept_internal() has
>>>> the
>>>> frequent_accept parameter defaulted to "false", yet, as far as I can
>>>> tell,
>>>> in this older version of the code, we always called it with "true".
>>>> Fwiw, I also checked v2.0.1, and it also had frequent_accept (as passed
>>>> around) default to true in every case.
>>>> 
>>> 
>>> MuxVC.cc, InkAPI.cc, and LogCollationAccept.cc call
>>> NetProcessor::accept() with frequent_accept false or defaulted. So it was
>>> not true everywhere.
>>> 
>> 
>> I see, yeah, that makes sense, I guess those auxiliary 'server' features
>> did not want to create multiple accept threads. I meant "always true" as in
>> for the main traffic_server process / HTTP server (i.e. there was no way to
>> make it false before).
>> 
>> 
>>> Perhaps we should leave the default true, but change the calls to
>>> NetProcessor::accept to set it false?
>>> 
>>> So, unless I'm totally missing something, just changing the default back
>>>> to
>>>> 'false' again will break accept_internal() as it was intended to work,
>>>> no ?
>>>> 
>>> accept_internal should be unaffected by the default. I think it was
>>> intended to check the value and do something based on it. Otherwise there
>>> should not even be an option to check.
>>> 
>>> The question is what the callers should do. I can try tweaking
>>> TSNetAccept to turn off frequent_accept, which is original (2.1.6) behavior
>>> (although that seems to make mock of the accept_threads parameter). We're
>>> still left with the question of why my code fails regression with fast
>>> accept.
>>> 
>> Alright, I think we are on the same page now. For some reason, I thought
>> you meant to turn off (set to false) the frequent_accept for the main
>> server. And like I said, I know we had that bug once before (before v2.1.7,
>> when you initially made the changes to pass the "opt" parameter, with it
>> defaulted to false). My concern is/was that we'd make the same mistake
>> again.
>> 
>> Seeing your explanation, the frequent_accept parameter does make some
>> sense, since there are (apparent) use cases where you don't want multiple
>> accept threads, or accepts per net-thread (for e.g. the log collation
>> server). So I don't think we should remove it (i.e. making it always on
>> seems like a bad idea).
>> 
>> It might be that we should clean this up though, a more obvious solution
>> would be to only have two options:
>> 
>>   1) One, or several, dedicated accept threads (e.g. num_accept_threads).
>> 
>>   2) Accept on one, or all, of the net-threads
>> 
>> 
>> This is basically the same as it works today, but less convoluted. If I
>> understand the code correct, if frequent_accept is false, then you get
>> assigned a "random" ET_NET thread to do the non-blocking accept() on. If it
>> is true, you either create one or several accept threads to do blocking
>> accept() on, or you do non-blocking accept() on all the net-threads.
>> 
>> Then all uses of this would allow for this, and specially, the InkAPI
>> accept APIs would allow for this control as well (unless they already do, I
>> didn't check).
>> 
>> Ciao,
>> 
>> -- Leif
>> 
>> 

Reply via email to