Make WordPress Core


Ignore:
Timestamp:
06/22/2021 09:23:19 PM (3 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.