You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Roy T. Fielding" <fi...@kiwi.ics.uci.edu> on 1998/03/07 04:28:11 UTC

Re: non-buffered CGIs suck

>Try running this:
>
>#include <sys/types.h>
>#include <sys/uio.h>
>#include <unistd.h>
>
>#define HEADERS "Content-type: text/plain\n\n"
>int main () {
>        char *s = "this is a line that is being sent\n ";
>        int i;
>        write(STDOUT_FILENO, HEADERS, strlen(HEADERS));
>        for (i = 0; i < 200; i++) {
>                write(STDOUT_FILENO, s, strlen(s));
>                usleep(1);
>
>        }
>}
>
>And you will see many small packets, it will take twice as long to
>transfer as buffered CGI did, etc.  It is not very nice to the network.

Well, of course not, which is a good reason why people don't include
microsleeps between every write.  It forces a context change, which
is something that does not happen in normal CGI scripts *unless*
the CGI is doing something that is expected to be slow, and in that
case we want the prior write to happen.

Non-buffered output works great with normal CGI scripts -- the remaining
scripts are insignificant (and can be fixed in the script itself).

....Roy

Re: non-buffered CGIs suck

Posted by Marc Slemko <ma...@worldgate.com>.
On Fri, 6 Mar 1998, Roy T. Fielding wrote:

> 
> Well, of course not, which is a good reason why people don't include
> microsleeps between every write.  It forces a context change, which
> is something that does not happen in normal CGI scripts *unless*
> the CGI is doing something that is expected to be slow, and in that
> case we want the prior write to happen.

No.  See the example I posted today; it shows how a simple perl script
trying to do something that appears perfectly reasonable, if slightly
inefficient, can do the same thing.  Say you write an indexing 
script so you want to run "file" on each file to try to figure out
what type of file it is so you can tell the client.  You will run into
this.  Say you want to output a sequence of data associated with
certain identifiers by looking up a list of keys in a DBM file and
outputting the data; you can run into this.

My patch is a start at making it output only if it is slow.  The current
code outputs whenever it possibly can.  There is a big difference.
I don't call a pause of 0.01 seconds "slow".  That sort of pause
is all that is required; you can come close to assuming that if it
has to give up its quantum for any reason, a separate segment will
go out.

> 
> Non-buffered output works great with normal CGI scripts -- the remaining
> scripts are insignificant (and can be fixed in the script itself).

I have to disagree.

What it all comes down to is that:

	1. Nagle is there for a reason.  If you define anything
	   that does small writes as broken and worthy of ignoring,
	   then Nagle has no purpose.

	2. Disabling Nagle is necessary in some applications that
	   require interactive responses, etc.  However, any application 
	   that disables it needs to be aware of what they are doing,
	   why they are doing it, and has to be certain not to 
	   do bad things like trying to use small writes for bulk 
	   data transfer.

The CGI doesn't talk to the network.  It hasn't disabled Nagle.  At
the very most, you should expect that it was written with the normal
network host in mind; that includes having Nagle enabled.  It is Apache
that is disabling it.  I am not comfortable with just saying that
it is the CGI's problem.

Again, I don't care what performance impact there is on the server.
I don't care what performance impact there is on the client.  I
don't care how slow it is.  Those are all things that are the CGI's
fault.  I do care about its impact on my network, and tinygrams
suck for bulk data transfer.