Skip to content

Commit

Permalink
Fix/6715 expiration update race conditions (#6750)
Browse files Browse the repository at this point in the history
  • Loading branch information
MathieuLamiot authored Jun 28, 2024
2 parents db3f345 + 6fcb948 commit 4fa6b9c
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions inc/Engine/Common/JobManager/APIHandler/AbstractSafeAPIClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,25 @@ public function send_post_request( $params = [], $safe = false ) {
private function send_request( $method, $params = [], $safe = false ) {
$api_url = $this->get_api_url();

if ( get_transient( $this->get_transient_key() . '_timeout_active' ) ) {
$transient_key = $this->get_transient_key();
if ( get_transient( $transient_key . '_timeout_active' ) ) {
return new WP_Error( 429, __( 'Too many requests.', 'rocket' ) );
}
// Get previous_expiration early to avoid multiple parallel requests increasing the expiration multiple times.
$previous_expiration = (int) get_transient( $transient_key . '_timeout' );

$params['method'] = strtoupper( $method );

$response = $this->send_remote_request( $api_url, $method, $params, $safe );

if ( is_wp_error( $response ) ) {
$this->set_timeout_transients();
$this->set_timeout_transients( $previous_expiration );
return $response;
}

$body = wp_remote_retrieve_body( $response );
if ( empty( $body ) || ( is_array( $response ) && ! empty( $response['response']['code'] ) && 200 !== $response['response']['code'] ) ) {
$this->set_timeout_transients();
$this->set_timeout_transients( $previous_expiration );
return new WP_Error( 500, __( 'Not valid response.', 'rocket' ) );
}

Expand All @@ -89,20 +92,21 @@ private function send_request( $method, $params = [], $safe = false ) {

/**
* Set the timeout transients.
*
* @param string $previous_expiration The previous value of _timeout_active transient.
*/
private function set_timeout_transients() {
private function set_timeout_transients( $previous_expiration ) {
$transient_key = $this->get_transient_key();

$timeout = (int) get_transient( $transient_key . '_timeout' );
$timeout = ( 0 === $timeout )
$expiration = ( 0 === $previous_expiration )
? 300
: ( 2 * $timeout <= DAY_IN_SECONDS
? 2 * $timeout
: ( 2 * $previous_expiration <= DAY_IN_SECONDS
? 2 * $previous_expiration
: DAY_IN_SECONDS
);

set_transient( $transient_key . '_timeout', $timeout, WEEK_IN_SECONDS );
set_transient( $transient_key . '_timeout_active', true, $timeout );
set_transient( $transient_key . '_timeout', $expiration, WEEK_IN_SECONDS );
set_transient( $transient_key . '_timeout_active', true, $expiration );
}

/**
Expand Down

0 comments on commit 4fa6b9c

Please sign in to comment.