2017-07-10 11:42 GMT+02:00 Luca Toscano <toscano.l...@gmail.com>: > Hi Rüdiger, > > 2017-07-10 8:31 GMT+02:00 Plüm, Rüdiger, Vodafone Group < > ruediger.pl...@vodafone.com>: > >> >> >> >> >> *Von:* Luca Toscano [mailto:toscano.l...@gmail.com] >> *Gesendet:* Samstag, 8. Juli 2017 09:52 >> *An:* Apache HTTP Server Development List <dev@httpd.apache.org> >> *Betreff:* Re: mod_proxy_fcgi and flush >> >> >> >> Hi Jacob, Helmut! >> >> >> >> 2017-07-06 20:54 GMT+02:00 Jacob Champion <champio...@gmail.com>: >> >> On 07/06/2017 11:13 AM, Jim Jagielski wrote: >> >> works 4 me... >> >> >> Doesn't for me. E.g. with a script like >> >> <?php >> print("hi!\n") >> flush(); >> sleep(1); >> print("hi!\n"); >> ?> >> >> it takes 1 second to receive a single chunk with both lines in it. >> >> From a quick skim I assume this is because we don't use nonblocking >> sockets in the proxy implementation. (There's even a note in mod_proxy_fcgi >> that says, "Yes it sucks to [get the actual data] in a second recv call, >> this will eventually change when we move to real nonblocking recv calls.") >> >> >> >> Quick check from my side too, so not sure if it makes sense. IIUC the >> comment is about getting all the headers from the FCGI backend >> (get_data_full(..., AP_FCGI_HEADER_LEN)), then get the response body in >> another one (the [actual data]). >> >> >> >> I checked mod_fcgi as Helmut suggested and it seems to me that the -flush >> feature is a simple "flush every data that you receive", so I tested the >> following patch with Jacob's php example code and it seems doing what >> Helmut asked (please correct me if I am wrong). >> >> >> >> Caveat: I had to set output_buffering = Off in my php-fpm's php.ini >> config file. >> >> >> >> http://home.apache.org/~elukey/httpd-2.4.x-mod_proxy_fcgi- >> force_flush.patch >> >> >> >> Flushing unconditionally is a bad idea performance wise. Please have a >> look how ajp solved this issue: >> >> >> >> https://svn.apache.org/r327185 >> >> https://svn.apache.org/r384580 >> >> https://svn.apache.org/r390210 >> >> https://svn.apache.org/viewvc/httpd/httpd/trunk/modules/prox >> y/mod_proxy_ajp.c?r1=325879&r2=390210 >> >> >> >> Hint: The above diff contains further unrelated changes. >> >> >> > Definitely, I added that quick and dirty patch to show my idea, really far > from being ready for a commit :) > Will review the commits that you posted, thanks! >
With a bit of delay I have something to share to the list :) I kept the following test as the "use case": <?php print("hi!\n") flush(); sleep(1); print("hi!\n"); ?> First of all, I tested it with httpd-trunk and it seems working fine thanks to several core non-blocking writes, removing the need of explicit FLUSH buckets. I am very ignorant about this part of httpd so I can't say much more, but it is really nice to see! I then checked Rüdiger's commits and this is my understanding about mod_ajp: - if "flushpackets" is set to "on" by mod_proxy then mod_proxy_ajp will insert a FLUSH bucket as soon as data is ready to be passed to the output filter chain. - if "flushpackets" is set to "auto" then mod_proxy_ajp will be a bit smarter and will apr_poll for "flushwait" seconds before inserting any FLUSH bucket, since new data might come from the backend and it would be more efficient to force a FLUSH with more data. IIUC mod_proxy_fcgi leverages the fact that the backend sends FCGI records with a predefined structure (FCGI_Record), containing "FCGI headers" (content len, padding len, version, type, etc..) that can be used to know how much data to expect from the backend. As far as I can see (with php-fpm) our use case is handled with multiple FCGI records, one for each "flush()" done in the php script. mod_proxy_fcgi does the following for each of them: 1) read the FCGI headers to gather how much data the record is carrying (clen) 2) read the data in iobuf_size batches, sending each time the bytes collected to the output filter chain. 3) finally read the padding bytes (if any). I tried to use the same trick as mod_ajp for flushpackets=auto, but apr_poll returned immediately most of the times due to the padding bytes ready to read (took me a while to realize this simple thing). I didn't find a real use case for flushpackets=auto in mod_proxy_fcgi, but I have two proposals for fluspackets=on: http://home.apache.org/~elukey/httpd-2.4.x-mod_proxy_fcgi-force_flush.patch http://home.apache.org/~elukey/httpd-2.4.x-mod_proxy_fcgi-force_flush-v2.patch The second one is a bit more conservative and does not insert the FLUSH bucket if it knows that the content len (clen) is bigger than the iobuf_size (since there is a goto that forces another get_data() in this case). Let me know if what I wrote make sense, suggestions and comments are welcome. It would be interesting to also know from Helmut a simple (PHP?) use case to use as a test, so I'll not base my code only on Jacob's example (that was really useful though!!). Thanks! Luca