[FASTCGI] libfcgi in multi threaded app
Rob
rclemley at booksys.com
Mon May 3 19:21:14 EDT 2010
Dave, Unless you actually answer the question of who's using these 3
variables, this will be my last post on this thread.
I know that my apps handle multi-threaded simultaneous concurrent
connections to web clients via [libfcgi - mod_fastcgi - apache2 - web
browsers], and both the docs and the source code support this.
Further comments below:
On 05/03/2010 02:45 PM, Dave Bender wrote:
> On Mon, May 3, 2010 at 3:30 PM, Rob <rclemley at booksys.com
> <mailto:rclemley at booksys.com>> wrote:
>
> The variables mentioned (FCGI_MPXS_CONNS, FCGI_MAX_REQS, and
> FCGI_MAX_CONNS) are not referenced anywhere in either the libfcgi
> or the apache2 mod_fastcgi libraries. They are set only in the
> code fragment you included, but never referenced.
>
>
> The only way the web server knows whether the fastcgi server can
> actually multiplex is through these variables. These variables are
> what inform the web server of the fastcgi server's capabilities.
> libfcgi reports it is incapable of multiplexing requests. Being hard
> coded responses, they are trivially not referenced by the rest of the
> code.
Where is the web server code which references these variables? The
Apache2 mod_fastcgi module is the web server code in question (in my
situation) and it doesn't use these variables. This is the crux of your
claim and you haven't shown that these variables are used.
> However in the introduction to the spec, we find this (emphasis mine):
>
> After a FastCGI process accepts a connection on its listening
> socket, the process executes a simple protocol to receive and
> send data. The protocol serves two purposes. /*First, the
> protocol multiplexes a single transport connection between
> several independent FastCGI requests. This supports
> applications that are able to **process concurrent requests
> using event-driven or multi-threaded programming techniques.
> Second, within each request the protocol provides several
> independent data streams in each direction.*/ This way, for
> instance, both stdout and stderr data pass over a single
> transport connection from the application to the Web server,
> rather than requiring separate pipes as with CGI/1.1.
>
> By using FCGX_Accept*_r*(), which keeps these streams separate,
> we're able to simultaneously handle multiple FastCGI connections
> within one App.
>
>
> Your conclusion is incorrect. There are only two input streams per
> request: params and stdin; these streams are not even concurrent;
> params must precede stdin. There are only two output streams per
> request: stdout and stderr. Keeping these streams separate is handled
> by parsing the headers of each packet, not by calling FCGX_Accept(_r)
The way the streams are kept separate is because we pass /a different
instance/ of the FCGX_Request structure to FCGX_Accept_r() every time.
All communication with the web server goes through these discrete
FCGX_Request structures, each of which maintains it's own streams, which
in turn is reflected in the protocol.
> Looking through the source, the first thing that FCGX_Accept_r does is
> call FCGX_Finish_r.
Which doesn't mean anything unless you re-use your FCGX_Request
structure. The FCGX_Finish_r called inside Accept_r is a no-op in my case.
> Also, in Appendix B, example #4, we see:
>
> 4. Two instances of example 1, multiplexed onto a single
> connection. The first request is more difficult than the
> second, so the application finishes the requests out of order:
> [...]
>
>
> I think the variables that we're discussing probably don't mean
> what you think they mean.
>
>
> Please read the spec and the source code more carefully.
??? Appendix B.4 clearly shows how the protocol maintains concurrent
requests.
That's a crude statement bordering on insult. Instructing me to "read
more carefully?" What does that say about you?
>
> Rob
>
>
>
> On 05/03/2010 01:32 PM, Dave Bender wrote:
>> Section 4.1 ( http://www.fastcgi.com/devkit/doc/fcgi-spec.html#SA
>> ) states:
>>
>> FCGI_MPXS_CONNS: "0" if this application does not multiplex
>> connections (i.e. handle concurrent requests over each
>> connection), "1" otherwise.
>>
>> Seeing as how the library is limited to 1 connection and 1 request,
>>
>> On Mon, May 3, 2010 at 2:27 PM, Rob <rclemley at booksys.com
>> <mailto:rclemley at booksys.com>> wrote:
>>
>> I cannot really address your question because you're touching
>> deeper into the internals of libfcgi and attempting to
>> reconcile it with "the spec", without explicit references to
>> which part of the spec. I just don't have time to do that
>> much research right now.
>>
>> Section 4.1 ( http://www.fastcgi.com/devkit/doc/fcgi-spec.html#SA
>> ) states:
>>
>> FCGI_MPXS_CONNS: "0" if this application does not multiplex
>> connections (i.e. handle concurrent requests over each
>> connection), "1" otherwise.
>>
>> This would imply connections are handled one at a time.
>>
>> I would guess that you're missing some understanding of the
>> complete flow of processing web requests, and how the
>> requests are handled in the various nooks and crannies of
>> FastCGI.
>>
>> Rob
>>
>>
>>
>> On 05/03/2010 12:22 PM, Dave Bender wrote:
>>> I'm also curious, how does the library even accept multiple
>>> requests simultaneously when the librar returns the
>>> following values for its management records:
>>>
>>> if(strcmp(name, FCGI_MAX_CONNS) == 0) {
>>> value = '1';
>>> } else if(strcmp(name, FCGI_MAX_REQS) == 0) {
>>> value = '1';
>>> } else if(strcmp(name, FCGI_MPXS_CONNS) == 0) {
>>> value = '0';
>>> } else {
>>> name = NULL;
>>> }
>>> (taken from fcgiapp.c, version 2.4.0)
>>>
>>> According to the spec, the web server should only be sending
>>> 1 at a time.
>>>
>>> -Dave
>>>
>>> On Mon, May 3, 2010 at 1:14 PM, Martin Chapman
>>> <chapmanm at pixia.com <mailto:chapmanm at pixia.com>> wrote:
>>>
>>> Rob,
>>>
>>> So how does this solution account for the fact that
>>> FCGX_Accept_r () resets
>>> the stdio global structure each time it's called? If
>>> you are synchronizing
>>> the code between each request, regardless of it's
>>> processed on a separate
>>> worker thread then only one request at a time is really
>>> being executed.
>>>
>>> Martin
>>>
>>>
>>> -----Original Message-----
>>> From: fastcgi-developers-bounces+chapmanm=pixia.com
>>> <http://pixia.com>@mailman.fastcgi.com
>>> <http://mailman.fastcgi.com>
>>> [mailto:fastcgi-developers-bounces+chapmanm
>>> <mailto:fastcgi-developers-bounces%2Bchapmanm>=pixia.com
>>> <http://pixia.com>@mailman.fastcgi.com
>>> <http://mailman.fastcgi.com>]
>>> On Behalf Of Rob
>>> Sent: Monday, May 03, 2010 11:06 AM
>>> To: fastcgi-developers at mailman.pins.net
>>> <mailto:fastcgi-developers at mailman.pins.net>
>>> Subject: Re: [FASTCGI] libfcgi in multi threaded app
>>>
>>> On 05/03/2010 10:27 AM, AlannY wrote:
>>> > I've created a socket via FCGX_OpenSocket. Everything
>>> all right.
>>> >
>>> > Then, I'm creating threads (5, for example). In each
>>> thread, I'm
>>> > creating a request with FCGX_InitRequest (with socket,
>>> created early and
>>> > FCGI_FAIL_ACCEPT_ON_INTR).
>>> >
>>> > Then the main loop starts. In this loop I'm calling
>>> FCGX_Accept_r on
>>> > this request. Here is trouble. Some of threads can
>>> successfully accept,
>>> > but some of then can't. Return code from FCGX_Accept
>>> is -9.
>>>
>>> The main thread loop should repeatedly call
>>> FCGX_Accept_r(). Requests
>>> successfully accepted by FCGX_Accept_r() must then be
>>> passed off to your
>>> worker threads for processing. Therefore, you might
>>> choose to
>>> dynamically allocate an fcgi request structure before
>>> calling
>>> FCGX_Accept_r() and then pass the dynamically allocated
>>> request
>>> structure to an available worker thread. The worker
>>> thread would then
>>> process the request and then deallocate the request.
>>>
>>> The multi-threaded problem is: "how to pass the requests
>>> to the worker
>>> threads?" Your program will be simple and graceful if
>>> you choose the
>>> means of a synchronized queue data structure. In a
>>> synchronized queue
>>> object, all of the thread synchronization is performed
>>> upon access to
>>> get or put items on the queue. The mutex guards access
>>> to the internal
>>> data. The conditions NotFull and NotEmpty signal the
>>> threads to wake up
>>> appropriately via the condition primitives: notify_one
>>> or notify_all.
>>> We use C++ and boost::threads to do something like this:
>>>
>>> pseudo code for main thread:
>>>
>>> synchronized_queue_class synchronized_queue #this
>>> is the only
>>> object that must be visible from all threads
>>>
>>> function get_fcgi_request( request )
>>> request = allocate(sizeof request)
>>> FCGX_init_request(request ...)
>>> if FCGX_Accept_r(request) is successful
>>> then return TRUE
>>> else return FALSE
>>> endif
>>> endfunction
>>>
>>> while get_fcgi_request( request )
>>> synchronized_queue.Put(request)
>>> endwhile
>>>
>>> pseudo code for worker threads:
>>>
>>> while synchronized_queue.Get(request)
>>> process(request)
>>> deallocate(request)
>>> endwhile
>>>
>>> pseudo code for synchronized_queue_class:
>>>
>>> class synchronized_queue_class:
>>> queue internal_queue
>>> condition notFull_condition
>>> condition notEmpty_condition
>>> mutex monitor
>>>
>>> procedure Put(item):
>>> scoped_lock(monitor)
>>> while internal_queue.full()
>>> notFull_condition.wait(monitor)
>>> internal_queue.put(item)
>>> notEmpty_condition.notify_one()
>>> endprocedure
>>>
>>> procedure Get(item):
>>> scoped_lock(monitor)
>>> while internal_queue.empty:
>>> notEmpty_condition.wait(monitor)
>>> internal_queue.push(item)
>>> notFull_condtion.notify_one()
>>> endprocedure
>>>
>>> endclass
>>>
>>> (There are other details in the synchronized queue which
>>> should be
>>> addressed, such as how to shut down the queue at the
>>> end of the program
>>> and tell the worker threads to exit.)
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> FastCGI-developers mailing list
>>> FastCGI-developers at mailman.fastcgi.com
>>> <mailto:FastCGI-developers at mailman.fastcgi.com>
>>> http://mailman.pins.net/mailman/listinfo.cgi/fastcgi-developers
>>>
>>> _______________________________________________
>>> FastCGI-developers mailing list
>>> FastCGI-developers at mailman.fastcgi.com
>>> <mailto:FastCGI-developers at mailman.fastcgi.com>
>>> http://mailman.pins.net/mailman/listinfo.cgi/fastcgi-developers
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.pins.net/mailman/private.cgi/fastcgi-developers/attachments/20100503/87209780/attachment-0001.html>
More information about the FastCGI-developers
mailing list