-
Notifications
You must be signed in to change notification settings - Fork 842
Improve Post Stats cache handling for invalid or error data #46211
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
Changes from 9 commits
e0ceb39
8877038
a736465
ffe8c0c
3c3624b
4ba2b0e
68d3fe3
3bbe021
5b9fc39
bd5a7b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Significance: patch | ||
| Type: changed | ||
|
|
||
| Improve Post Stats cache handling for invalid or error data |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -488,7 +488,11 @@ protected function fetch_stats( $args = array() ) { | |
| * | ||
| * Unlike the above function, this caches data in the post meta table. As such, | ||
| * it prevents wp_options from blowing up when retrieving views for large numbers | ||
| * of posts at the same time. However, the final response is the same as above. | ||
| * of posts at the same time. | ||
| * | ||
| * This function returns valid arrays and WP_Error objects from cache if within the expiration period. | ||
| * If the cached entry is malformed or invalid, a refresh is triggered regardless of cache time. | ||
| * This self-healing behavior reduces API calls when remote fetch fails, but ensures data validity. | ||
| * | ||
| * @param array $args Query parameters. | ||
| * @param int $post_id Post ID to acquire stats for. | ||
|
|
@@ -503,34 +507,56 @@ protected function fetch_post_stats( $args, $post_id ) { | |
| if ( $stats_cache ) { | ||
| $data = reset( $stats_cache ); | ||
|
|
||
| if ( | ||
| ! is_array( $data ) | ||
| || empty( $data ) | ||
| || is_wp_error( $data ) | ||
| ) { | ||
| return $data; | ||
| } | ||
| // Check if we have a valid cache structure with a time key. | ||
| if ( is_array( $data ) && ! empty( $data ) ) { | ||
| $time = key( $data ); | ||
|
|
||
| $time = key( $data ); | ||
| $views = $data[ $time ] ?? null; | ||
| // If we have a numeric time, check if cache is still valid. | ||
| if ( is_numeric( $time ) ) { | ||
| /** This filter is already documented in projects/packages/stats/src/class-wpcom-stats.php */ | ||
| $expiration = apply_filters( | ||
| 'jetpack_fetch_stats_cache_expiration', | ||
| self::STATS_CACHE_EXPIRATION_IN_MINUTES * MINUTE_IN_SECONDS | ||
| ); | ||
|
|
||
| // Bail if data is malformed. | ||
| if ( ! is_numeric( $time ) || ! is_array( $views ) ) { | ||
| return $data; | ||
| } | ||
| // If within cache period, return cached data after type validation. | ||
| if ( ( time() - $time ) < $expiration ) { | ||
| $cached_value = $data[ $time ]; | ||
|
|
||
| /** This filter is already documented in projects/packages/stats/src/class-wpcom-stats.php */ | ||
| $expiration = apply_filters( | ||
| 'jetpack_fetch_stats_cache_expiration', | ||
| self::STATS_CACHE_EXPIRATION_IN_MINUTES * MINUTE_IN_SECONDS | ||
| ); | ||
| // If it's an array or WP_Error, add cached time and return to user. | ||
| if ( is_array( $cached_value ) || is_wp_error( $cached_value ) ) { | ||
| return array_merge( array( 'cached_at' => $time ), (array) $cached_value ); | ||
| } | ||
kangzj marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
kangzj marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if ( ( time() - $time ) < $expiration ) { | ||
| return array_merge( array( 'cached_at' => $time ), $views ); | ||
| // For any other unexpected type, treat as malformed cache. | ||
| // Fall through to refresh. | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Cache doesn't exist, is expired, or is malformed - refresh it. | ||
| return $this->refresh_post_stats_cache( $endpoint, $args, $post_id, $meta_name ); | ||
| } | ||
|
|
||
| /** | ||
| * Force fetch stats from WPCOM, and always update cache. | ||
| * | ||
| * This function will cache the result regardless of whether the fetch succeeds | ||
| * or fails. This ensures that failed requests are also cached, reducing the | ||
| * frequency of API calls when the remote service is experiencing issues. | ||
| * | ||
| * @param string $endpoint The stats endpoint. | ||
| * @param array $args The query arguments. | ||
| * @param int $post_id The post ID. | ||
| * @param string $meta_name The meta name. | ||
| * | ||
| * @return array|WP_Error | ||
| */ | ||
| protected function refresh_post_stats_cache( $endpoint, $args, $post_id, $meta_name ) { | ||
| $wpcom_stats = $this->fetch_remote_stats( $endpoint, $args ); | ||
|
|
||
| // Always cache the result, even if it's an error or empty. | ||
| update_post_meta( $post_id, $meta_name, array( time() => $wpcom_stats ) ); | ||
|
|
||
| return $wpcom_stats; | ||
|
Comment on lines
+559
to
565
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.