This is an old revision of the document!
Run PHP without Timeouts
This wiki covers how to set up LiteSpeed Web Server so that a long-running PHP script will never timeout.
Reason
Some PHP scripts need to run for long periods of time without interruption. Examples include WordPress modules such as BackupBuddy, ImportBuddy, or any other module that relies on a WordPress built-in cron job. Whenever a PHP application rebuilds MySQL indexes, the process may run for a long time.
In Apache mod_php, the ignore_user_abort variable allows a user to trigger a long-running process and then close the browser or navigate away from the page without killing the PHP/MySQL process. This environment variable is not supported by LSWS.
How-To's
Generally, allowing a PHP script to run forever is not desirable. Thus there are a number of features that may prevent a PHP process from running as long as possible. You may need to set up more than one of the following configurations to ensure your application works correctly.
Turn off aborting for a broken connection
When a user closes a connection (by closing a window, for example), LSWS will abort processing that PHP script by killing the PHP process. This is to avoid wasting system resources and prevent certain types of DoS attacks.
In some cases, though, it is preferable to not to abort the PHP script regardless of whether the connection is still open. For example, Wordpress built-in cron jobs start a background job by sending a request to wp-cron.php
then immediately closing the connection without waiting for response. In order for the cron job to complete, though, the web server must keep the PHP engine running without interruption.
Aborting for a broken connection can be turned off at the server level in LSWS's WebAdmin console or by using the “noabort” environment variable.
Globally via the WebAdmin
WebAdmin console > Configuration > Server > General > External Application Abort
Set External Application Abort to “No Abort” to stop all applications from aborting even when a connection has been broken.
Through the "noabort" environment variable
Aborting for a broken connection can be turned off by using the request-level “noabort” environment variable. This can be done in a rewrite rule or using the SetEnv/SetEnvIf directives. “noabort” is a LiteSpeed-specifc environment variable.
The [E=noabort:1]
flag can be added to any rewrite rule. The rewrite rule can be in an Apache .htaccess file or vhost-level configuration file. The rewrite flag should usually be used in ONE account only. If you need to do a server-level configuration that will apply to all accounts (though perhaps only for certain scripts), you should use the SetEnvIf directive.
Rewrite rule examples:
- For all requests.
RewriteEngine On RewriteRule .* - [E=noabort:1]
- For
wp-cron.php
,backupbuddy.php,
andimportbuddy.php
only.
RewriteEngine On RewriteRule (wp-cron|backupbuddy|importbuddy)\.php - [E=noabort:1]
SetEnv/SetEnvIf directive examples:
- For all requests.
SetEnv noabort 1
- For certain URLs (i.e.
wp-cron.php
,backupbuddy.php,
andimportbuddy.php
).
SetEnvIf Request_URI “(wp-cron|backupbuddy|importbuddy)\.php” noabort
* Since rewrite rule cannot be easily inherited, if you use LiteSpeed with Apache httpd.conf, and want to apply noabort for certain url for all accounts, using SetEnvIf in the global section of httpd.conf will do it.
LiteSpeed connection timeout override
If a script does not send back anything for long time, server may close the client connection based on connection timeout, it means that the request could be aborted by the server or the client cannot see the result even though the script may continue to run till it finishes, depends on whether “noabort” has been set or not. You may want to prevent connection from being timed out some times.
Globally via server configuration
Admin CP => Configuration => Server => Tuning => Connection Timeout (secs)
Through "noconntimeout" environment variable
Similar to “noabort” environment, you can add “noconntimeout” environment variable via rewrite rule or SetEnv/SetEnvIf to turn off connection timeout.
RewriteEngine On RewriteRule .* - [E=noconntimeout:1]
RewriteRule (wp-cron|backupbuddy|importbuddy)\.php - [E=noconntimeout:1]
SetEnvIf Request_URI "(wp-cron|backupbuddy|importbuddy)\.php" noconntimeout
It can be combined with “noabort” environment variable.
RewriteRule (wp-cron|backupbuddy|importbuddy)\.php - [E=noabort:1, E=noconntimeout:1]
equivalent SetEnvIf directive is
SetEnvIf Request_URI "(wp-cron|backupbuddy|importbuddy)\.php" noabort noconntimeout
PHP execution time in php.ini
max_execution_time=36000
This is the time that spent in the PHP process itself (user time), does not include time spent in system calls or network I/O. Usually it takes more time to have it triggered.
LSAPI_MAX_PROCESS_TIME (set this environment variable in lsphp5)
Admin CP => Configuration => Server(or Vhost) => External App => lsphp5 => Environments
In Self Managed Mode, LSAPI_MAX_PROCESS_TIME (default 3600 seconds) controls the maximum processing time allowed when processing a request. If a child process cannot finish processing the request in the given time period, it will be killed by the parent process. This option can get rid of a dead or a runaway child process.
PHP coding
One of our customers has had success with the following PHP code. Code:
<?php //avoid apache to kill the php running ignore_user_abort(true); //start buffer output ob_start(); echo "show something to user"; //close session file on server side to avoid blocking other requests session_write_close(); //send length header header("Content-Length: ".ob_get_length()); header("Connection: close"); //really send content, can't change the order: //1.ob buffer to normal buffer, //2.normal buffer to output ob_end_flush(); flush(); //continue do something on server side ob_start(); //replace it with the background task sleep(50); ob_end_clean(); ?>
Note: You need to turn off keepalive for this request, which can be done with a rewrite rule.