Make WordPress Core

Opened 10 years ago

Closed 2 months ago

#29351 closed enhancement (wontfix)

Add a function for stampedes transient caching

Reported by: hypertextranch's profile hypertextranch Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.0
Component: Cache API Keywords:
Focuses: performance Cc:

Description

A common caching pattern that's used by WordPress and developers everywhere look something like this:

if ( false === ( $value = get_transient( $cache_key ) ) ) {
  // A
  // Bunch
  // Of
  // Code
  // $value = ...

  set_transient( $cache_key, $value, 300 );
}

The downside of this approach is when the cache is cold or when the cache expires there's a stampede effect as multiple requests try and refresh the cache at the same time. Instead if we had a function that allowed for soft expirations we could do something like the following:

$some_slow_func = function() {
  // A
  // Bunch
  // Of
  // Code
  // $value = ...

  return $value;
}

$value = get_set_soft_transient(
  $cache_key,
  $some_slow_func,
  300,
  'Some fake initial stale value'
);

This approach abstracts out the cache refresh logic into another function which can result in slightly cleaner code and can be used to prevent cache stampedes.

Some other optimizations / changes that we could do with this approach that's not yet implemented in the patch:

  • Run all cache refresh functions async via wp_cron so even the unlucky winner that gets to trigger the cache refresh will get stale data (fast).
  • Better locking so that only one request will refresh the cache. (Right now a couple requests could happen to refresh at the same time on a very busy site.)
  • Perhaps prevent caching of a false value or one that equates to the default passed in?
  • Use filters instead of PHP callbacks to make this more WordPress like.
  • Also build out get_set_soft_site_transient().

This is inspired by the stampedes cache @gibrown wrote for some of WordPress.com and the @mboynes talk at WordCamp Boston.

/cc @betzster

Attachments (1)

29351-initial-idea.patch (2.4 KB) - added by hypertextranch 10 years ago.
Initial idea patch

Download all attachments as: .zip

Change History (5)

@hypertextranch
10 years ago

Initial idea patch

#2 @jipmoors
9 years ago

I think the point is valid but with this patch you are polluting the transient space with meta data and not respecting existing data or the possibility that some code uses your function to set and other code uses get_transient to read the data.

Perhaps a separate meta transient would be a better option. Allowing for unmodified get_transient & set_transient functionality. This would increase cache / meta requests but I guess this functionality would only be used on large or slow data so would be worth it to provide the option to use it.

#3 @desrosj
23 months ago

  • Milestone set to Awaiting Review

#4 @pbearne
2 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

This is available as a plugin if needed

Note: See TracTickets for help on using tickets.