Skip to content

Commit 52d8caa

Browse files
authored
Drop retry strategy and up cache time (#461)
* Look for 429 for retries, and add a longer delay for airtable data source when it's rate limited * Switch the retry mechanism to be an exponential one * Change the backoff strategy to exponential * Remove unused code * Remove unused code * Go back to exponential with jitter * Tweak the minimum values * Switch to just exponential, and add a test * Re-enable caching * Remove the retry logic * Update the cache time, and add a new test for stale caches * Remove the new test as it's not practical * Update doc
1 parent 2eeb905 commit 52d8caa

File tree

5 files changed

+2
-123
lines changed

5 files changed

+2
-123
lines changed

docs/concepts/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ When a request to your site renders one or more remote data blocks, our plugin w
7272

7373
The plugin offers a caching layer for optimal performance and helps avoid rate limiting from remote data sources. It will be used if your WordPress environment configures a [persistent object cache](https://developer.wordpress.org/reference/classes/wp_object_cache/#persistent-cache-plugins). Otherwise, the plugin will utilize in-memory (per-page-load) caching. Deploying to production without a persistent object cache is not recommended.
7474

75-
The default TTL for all cache objects is 60 seconds, but it can be [configured per query or request](../extending/query.md#get_cache_ttl).
75+
The default TTL for all cache objects is 5 minutes, but it can be [configured per query or request](../extending/query.md#get_cache_ttl).
7676

7777
## Theming
7878

docs/extending/hooks.md

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -146,30 +146,3 @@ function custom_query_response_metadata( array $metadata, HttpQueryInterface $qu
146146
}
147147
add_filter( 'remote_data_blocks_query_response_metadata', 'custom_query_response_metadata', 10, 3 );
148148
```
149-
150-
### remote_data_blocks_http_client_retry_delay
151-
152-
Filter to change the defualt 1 second delapy after an HTTP request fails. The Remote Data Blocks Plugin uses the [Guzzle](https://github.com/guzzle/guzzle) HTTP client. You can read about the response interface in their [documentation](https://docs.guzzlephp.org/en/stable/).
153-
154-
```php
155-
function custom_response_retry_delay( int $retry_after_ms, int $retries, ?ResponseInterface $response ): int {
156-
// Implement a custom exponential backoff strategy.
157-
return floor( pow( 1.5, $retries ) * 1000 );
158-
}
159-
add_filter( 'remote_data_blocks_http_client_retry_delay', 'custom_response_retry_delay', 10, 3 );
160-
```
161-
162-
### remote_data_blocks_http_client_retry_decider
163-
164-
Filter the default HTTP retry logic when an HTTP request fails or encounters an exception. The Remote Data Blocks Plugin uses the [Guzzle](https://github.com/guzzle/guzzle) HTTP client. You can read about the request, response, and exception interfaces in their [documentation](https://docs.guzzlephp.org/en/stable/).
165-
166-
```php
167-
function custom_retry_decider( bool $should_retry, int $retries, RequestInterface $request, ?ResponseInterface $response, ?Exception $exception ): bool {
168-
// Retry on a 408 error if the number of retries is less than 5.
169-
if ( $retries < 5 && $response && 408 === $response->getStatusCode ) {
170-
return true;
171-
}
172-
return $should_retry;
173-
}
174-
add_filter( 'remote_data_blocks_http_client_retry_decider', 'custom_response_retry_on_exception', 10, 5 );
175-
```

inc/HttpClient/HttpClient.php

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22

33
namespace RemoteDataBlocks\HttpClient;
44

5-
use Exception;
65
use GuzzleHttp\HandlerStack;
76
use GuzzleHttp\Client;
8-
use GuzzleHttp\Exception\ConnectException;
97
use GuzzleHttp\MessageFormatter;
108
use GuzzleHttp\Middleware;
119
use GuzzleHttp\Promise\Utils;
@@ -21,8 +19,6 @@
2119
class HttpClient {
2220
public Client $client;
2321

24-
private const MAX_RETRIES = 3;
25-
2622
public const CACHE_TTL_CLIENT_OPTION_KEY = '__default_cache_ttl';
2723

2824
private string $base_uri;
@@ -79,11 +75,6 @@ public function init( string $base_uri, array $headers = [], array $client_optio
7975

8076
$this->handler_stack = HandlerStack::create( $request_handler );
8177

82-
$this->handler_stack->push( Middleware::retry(
83-
self::class . '::retry_decider',
84-
self::class . '::retry_delay'
85-
) );
86-
8778
$this->handler_stack->push( Middleware::mapRequest( function ( RequestInterface $request ) {
8879
foreach ( $this->headers as $header => $value ) {
8980
$request = $request->withHeader( $header, $value );
@@ -107,57 +98,6 @@ public function init( string $base_uri, array $headers = [], array $client_optio
10798
] ) );
10899
}
109100

110-
/**
111-
* Determine if the request request be retried.
112-
*
113-
* @param int $retries Number of retries that have been attempted so far.
114-
* @param RequestInterface $request Request that was sent.
115-
* @param ResponseInterface $response Response that was received.
116-
* @param Exception $exception Exception that was received (if any).
117-
* @return bool Whether the request should be retried.
118-
*/
119-
public static function retry_decider( int $retries, RequestInterface $request, ?ResponseInterface $response = null, ?Exception $exception = null ): bool {
120-
// Exceeding max retries is not overrideable.
121-
if ( $retries >= self::MAX_RETRIES ) {
122-
return false;
123-
}
124-
125-
$should_retry = false;
126-
127-
if ( $response && $response->getStatusCode() >= 500 ) {
128-
$should_retry = true;
129-
}
130-
131-
if ( $exception ) {
132-
$should_retry = $should_retry || $exception instanceof ConnectException;
133-
}
134-
135-
return apply_filters( 'remote_data_blocks_http_client_retry_decider', $should_retry, $retries, $request, $response, $exception );
136-
}
137-
138-
/**
139-
* Calculate the delay before retrying a request.
140-
*
141-
* @param int $retries Number of retries that have been attempted so far.
142-
* @param ResponseInterface $response Response that was received.
143-
* @return int Number of milliseconds to delay.
144-
*/
145-
public static function retry_delay( int $retries, ?ResponseInterface $response ): int {
146-
// Be default, implement a linear backoff strategy.
147-
$retry_after = $retries;
148-
149-
if ( $response instanceof ResponseInterface && $response->hasHeader( 'Retry-After' ) ) {
150-
$retry_after = $response->getHeaderLine( 'Retry-After' );
151-
152-
if ( ! is_numeric( $retry_after ) ) {
153-
$retry_after = ( new \DateTime( $retry_after ) )->getTimestamp() - time();
154-
}
155-
}
156-
157-
$retry_after_ms = (int) $retry_after * 1000;
158-
return apply_filters( 'remote_data_blocks_http_client_retry_delay', $retry_after_ms, $retries, $response );
159-
}
160-
161101
/**
162102
* Queue a request for later execution.
163103
*/

inc/HttpClient/RdbCacheStrategy.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
class RdbCacheStrategy extends GreedyCacheStrategy {
1616
private const CACHE_INVALIDATING_REQUEST_HEADERS = [ 'Authorization', 'Cache-Control' ];
17-
private const FALLBACK_CACHE_TTL_IN_SECONDS = 60;
17+
private const FALLBACK_CACHE_TTL_IN_SECONDS = 300; // 5 minutes
1818
private const WP_OBJECT_CACHE_GROUP = 'remote-data-blocks';
1919

2020
private Logger $logger;

tests/inc/HttpClient/HttpClientTest.php

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -60,40 +60,6 @@ public function testPost(): void {
6060
$this->assertSame( 'MISS', $response->getHeaderLine( RdbCacheMiddleware::HEADER_CACHE_INFO ) );
6161
}
6262

63-
public function testRetryDecider(): void {
64-
$request = new Request( 'GET', '/test' );
65-
66-
// Test max retries
67-
$this->assertFalse( HttpClient::retry_decider( 3, $request ) );
68-
69-
// Test 500 status code
70-
$response = new Response( 500 );
71-
$this->assertTrue( HttpClient::retry_decider( 0, $request, $response ) );
72-
73-
// Test ConnectException
74-
$exception = new ConnectException( 'Error Connecting', $request );
75-
$this->assertTrue( HttpClient::retry_decider( 0, $request, null, $exception ) );
76-
77-
// Test no retry on good response
78-
$response = new Response( 200 );
79-
$this->assertFalse( HttpClient::retry_decider( 0, $request, $response ) );
80-
}
81-
82-
public function testRetryDelay(): void {
83-
$response = new Response( 429, [ 'Retry-After' => '120' ] );
84-
$delay = HttpClient::retry_delay( 1, $response );
85-
$this->assertSame( 120000, $delay );
86-
87-
$response = new Response( 429, [ 'Retry-After' => ( new \DateTime( '+2 minutes' ) )->format( \DateTime::RFC7231 ) ] );
88-
$delay = HttpClient::retry_delay( 1, $response );
89-
$this->assertGreaterThan( 119000, $delay );
90-
$this->assertLessThan( 121000, $delay );
91-
92-
$response = new Response( 500 );
93-
$delay = HttpClient::retry_delay( 2, $response );
94-
$this->assertSame( 2000, $delay );
95-
}
96-
9763
public function testQueueRequestAndExecuteParallel(): void {
9864
$this->mock_handler->append( new Response( 200, [], 'Response 1' ) );
9965
$this->mock_handler->append( new Response( 201, [], 'Response 2' ) );

0 commit comments

Comments
 (0)