[wp-trac] [WordPress Trac] #46465: Implement logic that performs PHP code after connection with client is closed
WordPress Trac
noreply at wordpress.org
Mon Mar 11 16:20:07 UTC 2019
#46465: Implement logic that performs PHP code after connection with client is
closed
-------------------------+-----------------------------
Reporter: umchal | Owner: (none)
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version:
Severity: normal | Keywords:
Focuses: |
-------------------------+-----------------------------
Hi there,
It would be great if this can be implemented in the core.
When I write plugins, it is almost unavoidable to perform extra database
queries like accessing a custom database table, updating rows, and
scheduling WP Cron actions etc. The problem is that it affects the page
load time.
I've been wondering how this can be avoided and how the impact on the
performance can be made minimum from the user experience perspective.
And I came up with a little technique using `header('Content-Length: n')`
and `header('Connection: close' )`. Here is a working example plugin.
{{{#!php
<?php
/**
* Plugin Name: Test - HTTP Connection Close
*/
class HTTPConnectionClose {
public function __construct() {
add_action( 'init', array( $this, 'startCapturing' ) );
add_action( 'shutdown', array( $this, 'endCapturing' ),
PHP_INT_MIN );
}
public function startCapturing() {
ob_start();
}
/**
* @remark Should be called before `wp_ob_end_flush_all()`.
*/
public function endCapturing() {
$_iOutputBufferLength = ( integer ) ob_get_length();
if ( ! headers_sent() ) {
@header('Content-Length: ' . $_iOutputBufferLength ) ;
@header('Connection: close' );
}
if ( $_iOutputBufferLength ) {
ob_end_flush();
}
}
}
new HTTPConnectionClose;
}}}
Here are some examples that illustrate the benefits of this. You can add
this code at the bottom of the above example plugin.
{{{#!php
class Test_HTTPConnectionClose {
public function __construct() {
add_action( 'shutdown', array( $this, 'testHeavyTask' ),
PHP_INT_MAX );
add_action( 'plugins_loaded', array( $this, 'testWPCronCheck' ) );
add_action( 'shutdown', array( $this, 'testWPCronSchedule' ) );
add_action( 'test_custom_action', array( $this,
'testCustomCronTask' ) );
}
public function testCustomCronTask() {
error_log( __METHOD__ . ': doing custom cron task.' );
}
/**
* This causes a couple of database queries. But with the above
technique, this will not be seen during the page load.
*/
public function testWPCronSchedule() {
$_aArguments = array();
$_sActionName = 'test_custom_action';
if ( wp_next_scheduled( $_sActionName, $_aArguments ) ) {
return;
}
wp_schedule_single_event( time() + 5, $_sActionName, $_aArguments
);
}
/**
* Checks registered WP Cron actions in the `shutdown` instead of
`init` action
* to save a little load time in every single page load.
*/
public function testWPCronCheck() {
remove_action( 'init', 'wp_cron' );
if ( ! defined( 'DOING_CRON' ) ) {
add_action( 'shutdown', 'wp_cron' );
}
}
/**
* Simulates a heavy task which consumes 10 seconds. But with the
above technique, the visitor do not feel any delay caused by this.
*/
public function testHeavyTask() {
sleep( 10 ); // sleep 10 seconds
error_log( 'done a heavy task which takes 10 seconds.' );
}
}
new Test_HTTPConnectionClose;
}}}
As you can see with the above `testHeavyTask()` method, any heavy sub-
routines can be done in the `shutdown` action. Say, your plugin generates
outputs and has a caching mechanism that schedules a task and calls `wp-
cron.php` when the output is expired. With this, even scheduling a WP Cron
task will be no longer needed. The plugin can update the cache in the
`shutdown` action within the page load. This saves extra page load and
also helps avoid PHP timeout issues in `wp-cron.php` due to too many
registered WP Cron actions. Needless to say, this helps for sites
disabling WP Cron.
It's very short and should be technically feasible to implement. Not sure
any side effects with this yet but maybe you guys can tell.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/46465>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list