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 23 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
58 changes: 53 additions & 5 deletions inc/Engine/Preload/Controller/PreloadUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
return;
}

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

$requests = [
[
'url' => $url,
Expand Down Expand Up @@ -120,7 +123,12 @@
*/
'sslverify' => apply_filters( 'https_local_ssl_verify', false ), // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
]
);
);

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

/**
* Filters the arguments for the preload request.
Expand All @@ -136,10 +144,30 @@
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.

// Update average duration.
$previous_request_durations = get_transient( 'rocket_preload_previous_request_durations' ) ?? 0;
if ( $previous_request_durations <= 0 ) {
$previous_request_durations = $duration;
} else {

Check notice on line 163 in inc/Engine/Preload/Controller/PreloadUrl.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

inc/Engine/Preload/Controller/PreloadUrl.php#L163

The method preload_url uses an else expression. Else clauses are basically not necessary and you can simplify the code by not using them.
$previous_request_durations = $previous_request_durations * 0.7 + $duration * 0.3;
}
set_transient( 'rocket_preload_previous_request_durations', $previous_request_durations, 5 * 60 );

set_transient( 'rocket_preload_check_duration', $duration, 60 ); // Don't check request duration for 1 minute.
$check_duration = false;
}
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
/**
* Filter the delay between each preload request.
*
Expand Down Expand Up @@ -183,7 +211,24 @@

$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 estimaiton.
$max_batch_size = ( (int) apply_filters( 'rocket_preload_cache_pending_jobs_cron_rows_count', 45 ) ) - count( $pending_actions );
$min_batch_size = ( (int) apply_filters( 'rocket_preload_cache_min_in_progress_jobs_count', 5 ) );
Khadreal marked this conversation as resolved.
Show resolved Hide resolved
$preload_request_duration = get_transient( 'rocket_preload_previous_request_durations' );

// Estimate batch size based on request duration.
if ( ! $preload_request_duration ) {
$next_batch_size = $min_batch_size; // In case no estimation or there is an issue with the value.
} else {
// Linear function: 2s -> 45 jobs // 10s -> 5 jobs.
$next_batch_size = round( -5 * $preload_request_duration + 55 );
}
Khadreal marked this conversation as resolved.
Show resolved Hide resolved

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

// 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 @@ -198,11 +243,11 @@
* @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 @@ -215,10 +260,13 @@
}
);

// Make those hanging jobs failed.
foreach ( $stuck_rows as $row ) {
$this->query->make_status_failed( $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 ) ) {
Expand Down
2 changes: 2 additions & 0 deletions inc/Engine/WPRocketUninstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class WPRocketUninstall {
'wp_rocket_pricing_timeout',
'wp_rocket_pricing_timeout_active',
'rocket_get_refreshed_fragments_cache',
'rocket_preload_previous_request_durations',
'rocket_preload_check_duration',
];

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'sslverify' => false,
]
],
'transient' => 0,
]
],
'mobileNotActivatedShouldPreloadOnlyOnce' => [
Expand All @@ -24,13 +25,14 @@
'user_agent' => 'user_agent',
'request' => [
'config' => [
'blocking' => false,
'timeout' => 0.01,
'blocking' => true,
'timeout' => 20,
'user-agent' => 'WP Rocket/Preload',
'sslverify' => false,
]
],
]
'transient' => 1,
],
],
'mobileActivatedShouldPreloadTwice' => [
'config' => [
Expand All @@ -40,8 +42,8 @@
'user_agent' => 'user_agent',
'request' => [
'config' => [
'blocking' => false,
'timeout' => 0.01,
'blocking' => true,
'timeout' => 20,
'user-agent' => 'WP Rocket/Preload',
'sslverify' => false,
]
Expand All @@ -54,6 +56,7 @@
'sslverify' => false,
]
],
'transient' => 0,
]
]
];
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@
false,
true,
],
'rows' => 101,
'rows' => 5,
'jobs' => [
$row1,
$row2,
$row3
]
],
'transient' => 0,
],
'expected' => [
'outdated_jobs_id' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
],
[
'url' => 'http://example.org/test3',
'status' => 'pending'
'status' => 'failed'
],
[
'url' => 'http://example.org/test4',
Expand All @@ -147,15 +147,15 @@
],
[
'url' => 'http://example.org/test3',
'status' => 'pending'
'status' => 'failed'
],
[
'url' => 'http://example.org/test4',
'status' => 'pending'
'status' => 'in-progress'
],
[
'url' => 'http://example.org/test5',
'status' => 'pending'
'status' => 'in-progress'
],
],
'actions' => [
Expand All @@ -181,14 +181,14 @@
],
],
[
'exists' => false,
'exists' => true,
'args' => [
'hook' => 'rocket_preload_job_preload_url',
'args' => ['http://example.org/test4']
],
],
[
'exists' => false,
'exists' => true,
'args' => [
'hook' => 'rocket_preload_job_preload_url',
'args' => ['http://example.org/test5']
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 @@ -41,6 +41,8 @@ class Test_Uninstall extends FilesystemTestCase {
'rocket_preload_complete' => null,
'rocket_preload_complete_time' => null,
'rocket_preload_errors' => null,
'rocket_preload_previous_request_durations' => null,
'rocket_preload_check_duration' => null,
'rocket_database_optimization_process' => null,
'rocket_database_optimization_process_complete' => null,
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ protected function setUp(): void
* @dataProvider configTestData
*/
public function testShouldDoAsExpected($config) {
Functions\when( 'get_transient' )
->justReturn();
Functions\when( 'set_transient' )
->justReturn();

$this->options->expects()->get('do_caching_mobile_files', false)->andReturn($config['cache_mobile']);
$this->controller->expects()->is_already_cached($config['url'])->andReturn($config['cache_exists']);
$this->configureRequest($config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use WP_Rocket\Engine\Preload\Database\Queries\RocketCache;
use WP_Rocket\Tests\Unit\TestCase;
use Brain\Monkey\Filters;
use Brain\Monkey\Functions;

/**
* @covers \WP_Rocket\Engine\Preload\Controller\PreloadUrl::process_pending_jobs
Expand Down Expand Up @@ -38,7 +39,8 @@ protected function setUp(): void
* @dataProvider configTestData
*/
public function testShouldDoAsExpected($config, $expected) {

Functions\when( 'get_transient' )
->justReturn( $config['transient'] );
$this->queue->expects()->get_pending_preload_actions()->andReturn([]);
Filters\expectApplied('rocket_preload_cache_pending_jobs_cron_rows_count')->with(100)->andReturn($config['rows']);
$this->query->expects(self::once())->method( 'get_outdated_in_progress_jobs' )->with()->willReturn($config['outdated_jobs']);
Expand Down
Loading