Make WordPress Core


Ignore:
Timestamp:
06/22/2021 09:23:19 PM (5 years ago)
Author:
iandunn
Message:

Block Editor: Move caching to endpoint for unique responses.

Now that the pattern API request includes the locale and version, the cache key needs to contain a hash of the query args.

Props ocean90, dd32, timothyblynjacobs
Fixes #53435

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php

    r51206 r51208  
    112112                }
    113113
    114                 $api_url = add_query_arg(
    115                         array_map( 'rawurlencode', $query_args ),
    116                         'http://api.wordpress.org/patterns/1.0/'
    117                 );
    118 
    119                 if ( wp_http_supports( array( 'ssl' ) ) ) {
    120                         $api_url = set_url_scheme( $api_url, 'https' );
    121                 }
    122 
    123                 $wporg_response = wp_remote_get( $api_url );
    124                 $raw_patterns   = json_decode( wp_remote_retrieve_body( $wporg_response ) );
    125 
    126                 if ( is_wp_error( $wporg_response ) ) {
    127                         $wporg_response->add_data( array( 'status' => 500 ) );
    128 
    129                         return $wporg_response;
    130                 }
    131 
    132                 // Make sure w.org returned valid data.
    133                 if ( ! is_array( $raw_patterns ) ) {
    134                         return new WP_Error(
    135                                 'pattern_api_failed',
    136                                 sprintf(
    137                                 /* translators: %s: Support forums URL. */
    138                                         __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
    139                                         __( 'https://wordpress.org/support/forums/' )
    140                                 ),
    141                                 array(
    142                                         'status'   => 500,
    143                                         'response' => wp_remote_retrieve_body( $wporg_response ),
    144                                 )
     114                /*
     115                 * Include a hash of the query args, so that different requests are stored in
     116                 * separate caches.
     117                 *
     118                 * MD5 is chosen for its speed, low-collision rate, universal availability, and to stay
     119                 * under the character limit for `_site_transient_timeout_{...}` keys.
     120                 *
     121                 * @link https://stackoverflow.com/questions/3665247/fastest-hash-for-non-cryptographic-uses
     122                 */
     123                $transient_key = 'wp_remote_block_patterns_' . md5( implode( '-', $query_args ) );
     124
     125                /*
     126                 * Use network-wide transient to improve performance. The locale is the only site
     127                 * configuration that affects the response, and it's included in the transient key.
     128                 */
     129                $raw_patterns = get_site_transient( $transient_key );
     130
     131                if ( ! $raw_patterns ) {
     132                        $api_url = add_query_arg(
     133                                array_map( 'rawurlencode', $query_args ),
     134                                'http://api.wordpress.org/patterns/1.0/'
    145135                        );
     136
     137                        if ( wp_http_supports( array( 'ssl' ) ) ) {
     138                                $api_url = set_url_scheme( $api_url, 'https' );
     139                        }
     140
     141                        /*
     142                         * Default to a short TTL, to mitigate cache stampedes on high-traffic sites.
     143                         * This assumes that most errors will be short-lived, e.g., packet loss that causes the
     144                         * first request to fail, but a follow-up one will succeed. The value should be high
     145                         * enough to avoid stampedes, but low enough to not interfere with users manually
     146                         * re-trying a failed request.
     147                         */
     148                        $cache_ttl      = 5;
     149                        $wporg_response = wp_remote_get( $api_url );
     150                        $raw_patterns   = json_decode( wp_remote_retrieve_body( $wporg_response ) );
     151
     152                        if ( is_wp_error( $wporg_response ) ) {
     153                                $raw_patterns = $wporg_response;
     154
     155                        } elseif ( ! is_array( $raw_patterns ) ) {
     156                                // HTTP request succeeded, but response data is invalid.
     157                                $raw_patterns = new WP_Error(
     158                                        'pattern_api_failed',
     159                                        sprintf(
     160                                        /* translators: %s: Support forums URL. */
     161                                                __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
     162                                                __( 'https://wordpress.org/support/forums/' )
     163                                        ),
     164                                        array(
     165                                                'response' => wp_remote_retrieve_body( $wporg_response ),
     166                                        )
     167                                );
     168
     169                        } else {
     170                                // Response has valid data.
     171                                $cache_ttl = HOUR_IN_SECONDS;
     172                        }
     173
     174                        set_site_transient( $transient_key, $raw_patterns, $cache_ttl );
     175                }
     176
     177                if ( is_wp_error( $raw_patterns ) ) {
     178                        $raw_patterns->add_data( array( 'status' => 500 ) );
     179
     180                        return $raw_patterns;
    146181                }
    147182
Note: See TracChangeset for help on using the changeset viewer.