Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preload adaptative batch #6427

Merged
merged 54 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
f5f5e03
Rework Preload process_pending_jobs to adapt batch size based on prev…
MathieuLamiot Jan 15, 2024
fbdeb7e
Rework the batch size to depend on a request duration measurement
MathieuLamiot Jan 18, 2024
375d2ec
Set transient expiration
MathieuLamiot Jan 18, 2024
a0af9fc
Move code around to limit changes
MathieuLamiot Jan 18, 2024
c5763cf
Compute all request duration, used to determine the next batch size
Khadreal Jan 26, 2024
42f85be
Modified computation as suggested by @mathieu
Khadreal Jan 29, 2024
52eab5f
Clean float to int conversion
MathieuLamiot Jan 29, 2024
38fe3e4
Prevent the check_duration to happen for every AS task
MathieuLamiot Jan 29, 2024
73c7dbc
Bring back behaviors like delay_between and limit on number of pendin…
MathieuLamiot Jan 30, 2024
979e196
Fix blocking headers that was not applied
MathieuLamiot Jan 30, 2024
640b383
Adjust batch size formula based on local and gamma experiments
MathieuLamiot Feb 1, 2024
4716dc6
Merge commit '163edfebd3cfa77be5ae824858755af9034a9915' into prototyp…
MathieuLamiot Feb 1, 2024
7eb83c9
fix linter
MathieuLamiot Feb 1, 2024
320bc7e
Fix typo while fixing linter... duh
MathieuLamiot Feb 1, 2024
2986803
Improve testing
Khadreal Feb 14, 2024
93c3e48
Add get-transient method to test method
Khadreal Feb 14, 2024
0cfb05e
Fixed undefined test error
Khadreal Feb 14, 2024
159840d
Modified test method :phew:
Khadreal Feb 14, 2024
ab3c7bf
Modified testing
Khadreal Feb 14, 2024
0865788
Fixed test error :feat:
Khadreal Feb 14, 2024
4b9f966
fixed integration test
Khadreal Feb 15, 2024
3761107
Add transients
Khadreal Feb 15, 2024
25a43d0
fixed lint error
Khadreal Feb 15, 2024
3c70603
Review modifications, add comment to filter
Khadreal Feb 28, 2024
18f4178
code modification :sparkles:
Khadreal Feb 29, 2024
c4cca9c
Change package version and modify preload url loop
Khadreal Feb 29, 2024
a1662ff
Make the max size of the preload batch the top priority constraint to…
MathieuLamiot Mar 11, 2024
8951cc3
Fix tests
MathieuLamiot Mar 11, 2024
3a9a2ad
InProgressShouldNotExceedMaxQueue data set needs update
MathieuLamiot Mar 11, 2024
959f8f8
Merge branch 'develop' into prototype/preload-adaptative-batch
Tabrisrp Jun 12, 2024
cd57efa
update test config
Tabrisrp Jun 12, 2024
ba634ac
fix function name
Tabrisrp Jun 12, 2024
8e8e205
update count expectation
Tabrisrp Jun 12, 2024
d6beb2f
force int type
Tabrisrp Jun 12, 2024
daba361
cleanup
Tabrisrp Jun 12, 2024
16f4dbb
update expectations
Tabrisrp Jun 12, 2024
1c7b9c2
update test config
Tabrisrp Jun 12, 2024
70f0f71
update condition
Tabrisrp Jun 12, 2024
1b99daa
add test for check duration
Tabrisrp Jun 12, 2024
2483a46
update transient name and code
Tabrisrp Jun 13, 2024
9d68828
update transient name
Tabrisrp Jun 13, 2024
f806482
improve expectations for transients
Tabrisrp Jun 13, 2024
b1ab24b
rename variable
Tabrisrp Jun 13, 2024
d00b8ee
code cleanup
Tabrisrp Jun 13, 2024
b3a1d27
Merge commit '5b286ce8c571285bd0924f8f223440e7f9f4c0b4' into prototyp…
MathieuLamiot Jun 25, 2024
2f34f9d
add logs
MathieuLamiot Jun 25, 2024
f016139
Fix log typo
MathieuLamiot Jun 25, 2024
48f03ee
Revert "Fix log typo"
MathieuLamiot Jun 25, 2024
eeb8c34
Revert "add logs"
MathieuLamiot Jun 25, 2024
43fbc5d
revert logs as we have the transients already
MathieuLamiot Jun 25, 2024
495d749
Revert "revert logs as we have the transients already"
MathieuLamiot Jun 25, 2024
f4c9af6
cast next_batch_size to int
MathieuLamiot Jun 26, 2024
cab5b28
fix linter
MathieuLamiot Jun 26, 2024
57eb141
Merge branch 'refs/heads/develop' into prototype/preload-adaptative-b…
wordpressfan Jul 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 72 additions & 9 deletions inc/Engine/Preload/Controller/PreloadUrl.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);

namespace WP_Rocket\Engine\Preload\Controller;

Expand Down Expand Up @@ -56,16 +57,20 @@ public function __construct( Options_Data $options, Queue $queue, Cache $rocket_
* Preload an url.
*
* @param string $url url to preload.
*
* @return void
*/
public function preload_url( string $url ) {

$is_mobile = $this->options->get( 'do_caching_mobile_files', false );

if ( $this->is_already_cached( $url ) && ( ! $is_mobile || $this->is_already_cached( $url, true ) ) ) {
$this->query->make_status_complete( $url );
return;
}

// Should we perform a duration check?
$check_duration = ( false === get_transient( 'rocket_preload_check_duration' ) ) ? true : false;

$requests = [
[
'url' => $url,
Expand Down Expand Up @@ -117,6 +122,11 @@ public function preload_url( string $url ) {
]
);

if ( $check_duration ) {
$headers['blocking'] = true;
$headers['timeout'] = 20;
}

/**
* Filters the arguments for the preload request.
*
Expand All @@ -131,19 +141,42 @@ public function preload_url( string $url ) {
return;
}

if ( $check_duration ) {
$start = microtime( true );
}

wp_safe_remote_get(
user_trailingslashit( $request['url'] ),
$headers
);

if ( $check_duration ) {
$duration = ( microtime( true ) - $start ); // Duration of the request.
}

/**
* Filter the delay between each preload request.
*
* @param float $delay_between the defined delay.
* @returns float
*/
$delay_between = apply_filters( 'rocket_preload_delay_between_requests', 500000 );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's not been added by this PR, but shouldn't we add a safeguard here ?


usleep( $delay_between );

if ( ! $check_duration ) {
continue;
}

$duration_transient = get_transient( 'rocket_preload_previous_requests_durations' );
$average_duration = ( false !== $duration_transient ) ? $duration_transient : 0;

// Update average duration.
$average_duration = ( $average_duration <= 0 ) ? $duration : ( $average_duration * 0.7 + $duration * 0.3 );

set_transient( 'rocket_preload_previous_requests_durations', $average_duration, 5 * MINUTE_IN_SECONDS );

set_transient( 'rocket_preload_check_duration', $duration, MINUTE_IN_SECONDS ); // Don't check request duration for 1 minute.
$check_duration = false;
}
}

Expand Down Expand Up @@ -175,10 +208,37 @@ protected function get_mobile_user_agent_prefix() {
* @return void
*/
public function process_pending_jobs() {

$pending_actions = $this->queue->get_pending_preload_actions();

$count = ( (int) apply_filters( 'rocket_preload_cache_pending_jobs_cron_rows_count', 45 ) ) - count( $pending_actions );
// Retrieve batch size limits and request timing estimation.
/**
* Get the number of pending cron job
*
* @param int $args Maximum number of job size.
*/
$max_batch_size = ( (int) apply_filters( 'rocket_preload_cache_pending_jobs_cron_rows_count', 45 ) ) - count( $pending_actions );

/**
* Get the number of in progress cron job
*
* @param int $args Minimum number of job size.
*/
$min_batch_size = ( (int) apply_filters( 'rocket_preload_cache_min_in_progress_jobs_count', 5 ) );

$average_duration = get_transient( 'rocket_preload_previous_requests_durations' );

/**
* Estimate batch size based on request duration.
* In case no estimation or there is an issue with the value use $min_batch_size.
*/
$next_batch_size = ! $average_duration ? $min_batch_size : round( -5 * $average_duration + 55 );

// Limit next_batch_size.
$next_batch_size = max( $next_batch_size, $min_batch_size ); // Not lower than 5.
$next_batch_size = min( $next_batch_size, $max_batch_size ); // Not higher than 45.
$next_batch_size = max( $next_batch_size, 0 ); // Not lower than 0.

// Get all in-progress jobs with request sent and no results.
/**
* Set the delay before an in-progress row is considered as outdated.
*
Expand All @@ -193,11 +253,11 @@ public function process_pending_jobs() {
* @param int $count number of rows in batches.
* @return int
*/
(int) ( $count / 15 )
(int) ( $max_batch_size / 15 )
);

$stuck_rows = $this->query->get_outdated_in_progress_jobs( $delay );

// Make sure the request has been sent for those jobs.
$stuck_rows = array_filter(
$stuck_rows,
function ( $row ) use ( $pending_actions ) {
Expand All @@ -210,18 +270,21 @@ function ( $row ) use ( $pending_actions ) {
}
);

// Make those hanging jobs failed.
foreach ( $stuck_rows as $row ) {
$this->query->make_status_failed( $row->id );
$this->query->make_status_failed( (int) $row->id );
}
$rows = $this->query->get_pending_jobs( $count );

// Add new jobs in progress.
$rows = $this->query->get_pending_jobs( $next_batch_size );
foreach ( $rows as $row ) {

if ( $this->is_excluded_by_filter( $row->url ) ) {
$this->query->delete_by_url( $row->url );
continue;
}

$this->query->make_status_inprogress( $row->id );
$this->query->make_status_inprogress( (int) $row->id );
$this->queue->add_job_preload_job_preload_url_async( $row->url );

}
Expand Down
2 changes: 2 additions & 0 deletions inc/Engine/WPRocketUninstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class WPRocketUninstall {
'wp_rocket_pricing_timeout',
'wp_rocket_pricing_timeout_active',
'rocket_get_refreshed_fragments_cache',
'rocket_preload_previous_requests_durations',
'rocket_preload_check_duration',
];

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?php
return [
'alreadyPresentShouldDoNothing' => [
'shouldDoNothingWhenAlreadyCached' => [
'config' => [
'transient_check_duration' => 500,
'url' => 'url',
'cache_exists' => true,
'cache_mobile' => false,
Expand All @@ -12,12 +13,13 @@
'timeout' => 0.01,
'user-agent' => 'WP Rocket/Preload',
'sslverify' => false,
]
],
],
]
],
],
'mobileNotActivatedShouldPreloadOnlyOnce' => [
'shouldPreloadOnlyOnceWhenMobileCacheDisabled' => [
'config' => [
'transient_check_duration' => 500,
'url' => 'url',
'cache_exists' => false,
'cache_mobile' => false,
Expand All @@ -28,12 +30,13 @@
'timeout' => 0.01,
'user-agent' => 'WP Rocket/Preload',
'sslverify' => false,
]
],
],
]
],
],
'mobileActivatedShouldPreloadTwice' => [
'ShouldPreloadTwiceWhenMobileCacheEnabled' => [
'config' => [
'transient_check_duration' => 500,
'url' => 'url',
'cache_exists' => false,
'cache_mobile' => true,
Expand All @@ -44,16 +47,33 @@
'timeout' => 0.01,
'user-agent' => 'WP Rocket/Preload',
'sslverify' => false,
]
],
],
'request_mobile' => [
'config' => [
'blocking' => false,
'timeout' => 0.01,
'user-agent' => 'user_agent',
'sslverify' => false,
]
],
],
]
]
],
],
'shouldPreloadOnlyOnceWhenMobileCacheDisabledAndCheckDuration' => [
'config' => [
'transient_check_duration' => false,
'url' => 'url',
'cache_exists' => false,
'cache_mobile' => false,
'user_agent' => 'user_agent',
'request' => [
'config' => [
'blocking' => true,
'timeout' => 20,
'user-agent' => 'WP Rocket/Preload',
'sslverify' => false,
],
],
],
],
];
Original file line number Diff line number Diff line change
Expand Up @@ -41,34 +41,35 @@
'shouldPassJobsInPending' => [
'config' => [
'outdated_jobs' => [
$outdated_row
$outdated_row,
],
'excluded' => [
false,
false,
true,
false,
false,
true,
],
'rows' => 101,
'rows' => 5,
'jobs' => [
$row1,
$row2,
$row3
]
$row3,
],
'transient' => 0,
],
'expected' => [
'outdated_jobs_id' => [
[14]
[ 14 ],
],
'job_ids' => [
[10],
[11],
[ 10 ],
[ 11 ],
],
'job_urls' => [
'http://example1',
'http://example2',
],
'job_deleted' =>
['http://example3'],
]
[ 'http://example3' ],
],
],
];
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
],
'InProgressShouldNotExceedMaxQueue' => [
'config' => [
'rocket_preload_cache_pending_jobs_cron_rows_count' => 3,
'rocket_preload_cache_pending_jobs_cron_rows_count' => 5,
'manual_preload' => true,
'rocket_preload_outdated' => 1000,
'rows' => [
Expand All @@ -120,7 +120,7 @@
],
[
'url' => 'http://example.org/test3',
'status' => 'pending'
'status' => 'in-progress'
],
[
'url' => 'http://example.org/test4',
Expand All @@ -147,11 +147,11 @@
],
[
'url' => 'http://example.org/test3',
'status' => 'pending'
'status' => 'in-progress'
],
[
'url' => 'http://example.org/test4',
'status' => 'pending'
'status' => 'in-progress'
],
[
'url' => 'http://example.org/test5',
Expand Down Expand Up @@ -181,7 +181,7 @@
],
],
[
'exists' => false,
'exists' => true,
'args' => [
'hook' => 'rocket_preload_job_preload_url',
'args' => ['http://example.org/test4']
Expand Down
2 changes: 2 additions & 0 deletions tests/Integration/inc/Engine/WPRocketUninstall/uninstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class Test_Uninstall extends FilesystemTestCase {
'rocket_preload_complete' => null,
'rocket_preload_complete_time' => null,
'rocket_preload_errors' => null,
'rocket_preload_previous_requests_durations' => null,
'rocket_preload_check_duration' => null,
'rocket_database_optimization_process' => null,
'rocket_database_optimization_process_complete' => null,
'rocket_hide_deactivation_form' => null,
Expand Down
Loading
Loading