Skip to content

Commit

Permalink
Map: Only schedule crons for cacheable requests
Browse files Browse the repository at this point in the history
There's no point to scheduling a cron for a non-caching request, because there's no cached value to prime.
  • Loading branch information
iandunn committed Dec 7, 2023
1 parent 17510b9 commit c62246d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
36 changes: 27 additions & 9 deletions mu-plugins/blocks/google-map/inc/event-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

/**
* Schedule a cron job to update events that match the given filter/dates.
*
* This makes sure that there's always a fresh cache, so that users never experience a delay while waiting for a
* stale one to be renewed.
*/
function schedule_filter_cron( string $filter_slug, string $start_date, string $end_date, array $facets = array() ): void {
$cron_args = array( $filter_slug, $start_date, $end_date, $facets, true );
Expand All @@ -32,19 +35,15 @@ function schedule_filter_cron( string $filter_slug, string $start_date, string $
* Get events matching the provider filter during the given timeframe.
*/
function get_events( string $filter_slug, int $start_timestamp, int $end_timestamp, array $facets = array(), bool $force_refresh = false ) : array {
$cacheable = true;
$events = array();
$page = get_query_var( 'paged' ) ? absint( get_query_var( 'paged' ) ) : 1;
$facets = array_filter( $facets ); // Remove empty so that `count()` below is accurate.

if ( ! empty( $facets['search'] ) || count( $facets ) > 1 || $page !== 1 ) {
// Search terms vary so much that caching them probably wouldn't result in a significant degree of
// cache hits, but it would generate a lot of extra transients. With memcached, that could push
// more useful values out of the cache. Old pages are similar.
$cacheable = false;
}
$facets = array_filter( $facets ); // Remove empty.
$cacheable = is_cacheable( $facets, $page );

if ( $cacheable ) {
// This has to be called here so that the facets match the ones used to generate the cache.
schedule_filter_cron( $filter_slug, $start_timestamp, $end_timestamp, $facets );

$cache_key = get_cache_key( array_merge(
compact( 'filter_slug', 'start_timestamp', 'end_timestamp' ),
$facets // It's safe to include this because of the logic around `$cacheable`.
Expand Down Expand Up @@ -88,13 +87,32 @@ function get_events( string $filter_slug, int $start_timestamp, int $end_timesta
return $events;
}

/**
* Determine if the given request is cacheable.
*/
function is_cacheable( array $facets, int $page ): bool {
$cacheable = true;
$facets = array_filter( $facets ); // Remove empty so that `count()` below is accurate.

// Only cache regularly visited pages.
// Search terms vary so much that caching them probably wouldn't result in a significant degree of
// cache hits, but it would generate a lot of extra transients. With memcached, that could push
// more useful values out of the cache. Old pages and multi-facet requests are similar.
if ( ! empty( $facets['search'] ) || count( $facets ) > 1 || $page !== 1 ) {
$cacheable = false;
}

return $cacheable;
}

/**
* Get the cache key for a given set of events.
*
* Customizing the key is sometimes needed when using the `google_map_event_filters_{$filter_slug}` filter.
* See WordCamp's `themes/wporg-events-2023/inc/city-landing-pages.php` for an example.
*/
function get_cache_key( array $parts ): string {
$parts = array_filter( $parts ); // Remove empty so that cache key is normalized.
$items = apply_filters( 'google_map_event_filters_cache_key_parts', $parts );
$key = 'google-map-event-filters-' . md5( wp_json_encode( implode( '|', $items ) ) );

Expand Down
5 changes: 1 addition & 4 deletions mu-plugins/blocks/google-map/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ function render( $attributes, $content, $block ) {
$attributes['markerIcon']['markerAnchorXOffset'] = $attributes['markerIcon']['markerWidth'] / -4;

if ( ! empty( $attributes['filterSlug'] ) ) {
$attributes['markers'] = get_events( $attributes['filterSlug'], $attributes['startDate'], $attributes['endDate'] );

// This has to be called in `render()` to know which slug/dates to use.
schedule_filter_cron( $attributes['filterSlug'], $attributes['startDate'], $attributes['endDate'] );
$attributes['markers'] = get_events( $attributes['filterSlug'], $attributes['startDate'], $attributes['endDate'], array() );
}

$handles = array( $block->block_type->view_script_handles[0], $block->block_type->editor_script_handles[0] );
Expand Down

0 comments on commit c62246d

Please sign in to comment.