views:

294

answers:

3

I am responsible for the backend portion of an API, written in PHP, which is primarily used by a Flash client. What happens right now is: the Flash client makes a call, the backend loads the necessary data, does any necessary processing and post processing, logging and caching and then returns the result to the client.

What I would like to have happen is return the data to the client as soon as possible, close the connection, and then do all the stuff that the client doesn't have to care about. This could make the API seem much more responsive. Following the suggestions here:

http://php.net/manual/en/features.connection-handling.php

actually works, except that I have to turn off gzip encoding in order to make it work, which isn't very practical. We use mod_deflate in apache, so a solution that works with that would be ideal, but I would also consider a different method to gzip our content if that is necessary.

It seems like there should be a way to let Apache know "I've sent you all the data I'm going to send," but I can't seem to find anything like that.

For those wondering, yes I can flush the results early, but the Flash client will not process them until the connection is closed.

+2  A: 

You might try breaking it into two pages.

In the first page, do the necessary processing, then load the second page via curl, and die().

That would cause the first page to complete and close, independent of the second page processing.

ie:

Page 1:

<?php

// Do stuff

// Post or get second page...

// Send Data to client

die();
?>

Page 2:

<?php

// Do other stuff....

?>

See http://www.php.net/curl

Eli
Thanks. I'm aware of a few workarounds for this issue, some more elegant than others, but I'd really like to find a way to just tell Apache to stop waiting for output and close the connection. :)
Jay Paroline
A: 

There's a kind of hack to do this by placing the code you want to execute after the connection closes within a callback method registered via to register_shutdown_function();

Theo.T
Ooh, shiny! I'll try that tomorrow.
Jay Paroline
No luck. The following prints out the extra crap and takes the full execution time to close the connection when using mod_deflate:function sleepLongTime() { print "you can't see this"; sleep(30); }ob_end_clean();register_shutdown_function('sleepLongTime');header("Connection: close\r\n");ignore_user_abort(true);ob_start();echo ('Text user will see');ob_end_flush();flush();ob_end_clean();die();
Jay Paroline
A: 

@Theo.T since the comment system mangled the crap out of my code, I'm posting it here:

No luck. The following prints out the extra crap and takes the full execution time to close the connection when using mod_deflate:

function sleepLongTime() { 
    print "you can't see this";
    sleep(30);
}
ob_end_clean();
register_shutdown_function('sleepLongTime');
header("Connection: close\r\n");
ignore_user_abort(true);
ob_start();
echo ('Text user will see');
ob_end_flush();
flush();
ob_end_clean();
die();
Jay Paroline