Graham,

thanks for the explanations and the hint to mod_proxy. I am now able to use 
pools/subpools and bucket_alloctors in a better way which improves overall 
performance.

Just for the record: the important thing to learn for me was that there is 
another layer underneath apr_pool_t called apr_allocator_t which is not  
thread-safe by default - but can be made so. With my own allocator per real 
connection and a mutex protecting it, I can pool and subpool to my heart's 
content across threads. In my measurements, the disadvantage of a mutex'ed 
allocator is much overcompensated by proper pool/memory reuse, e.g. it is 
faster.

Cheers,

  Stefan


> Am 17.03.2015 um 23:52 schrieb Graham Leggett <minf...@sharp.fm>:
> 
> On 17 Mar 2015, at 15:59, Stefan Eissing <stefan.eiss...@greenbytes.de> wrote:
> 
>> 
>> Hi,
>> 
>> I have a question regarding my http2 module implementation, where I seem to 
>> fail to wrap my head around the limitations of pools and bucket brigades in 
>> a multi-threaded environment. As I understand it, httpd has - so far - the 
>> underlying assumption:
>> 
>> 1 connection -> 1 request -> 1 thread
>> 
>> at a single point in time. This used to be quite static, as in mpm_worker, 
>> and was made more dynamic with mpm_event, which may switch the thread 
>> around. However even though entities might be exchanged, it is always 1-1-1 
>> at a single point in time.
>> 
>> Now, as most of you are aware, with the HTTP/2 processing model, this holds 
>> no longer true. The relation there is 1-m-m* and, worse, the connection is 
>> multiplexing requests, so there are many active at the same time and their 
>> data will be interleaved. The request/thread coupling can stay as it is, but 
>> the connection relation is different.
>> 
>> I today have a working implementation and it has major drawbacks (among all 
>> the bugs I need to find):
>> 
>> 1. it mimicks httpd objects that are not really there, e.g. 
>> pseudo-connections, so that there seems to be a 1-1 with connections and 
>> requests again (just as mod_spdy does). Therefore it needs to fake HTTP/1.1 
>> requests, so that core filter can parse them, etc.
>> 
>> 2. beautiful apr infrastructure like bucket brigades are not used when data 
>> needs to be passed between threads.
>> 
> 
>> I have made an attempt today to make bucket brigades work for passing data 
>> between threads, but things keep crashing on me when load grows. Which is 
>> all my fault for not understanding these things fully. So, am I on a fool's 
>> errand? Can I have brigade A in thread 1 and brigade B in thread 2 and pass 
>> buckets between them without excessive copying? I think I am doing it wrong 
>> and the cleanups of the allocators run in the wrong thread in the end which 
>> is not healthy.
> 
> One place where you can get a concrete example of data in one pool lifetime 
> being transferred across to another is in mod_proxy - the backend connection 
> comes out of a pool, and may live longer or shorter than the request going 
> out the front.
> 
> Getting this right is tricky, you need to be particular about the pool 
> lifetimes.
> 
> Pools create a hierarchy, that is the key. If you have requests subordinate 
> to a connection, ie when the connection dies the requests die, let the 
> request be a subpool of the connection.
> 
> You may have many independent requests linked to the same connection, just 
> make sure the requests don't leak into each other.
> 
> Regards,
> Graham
> --

<green/>bytes GmbH
Hafenweg 16, 48155 Münster, Germany
Phone: +49 251 2807760. Amtsgericht Münster: HRB5782



Reply via email to