Skip to content

v1.2.3

Choose a tag to compare

@hostney hostney released this 27 Aug 20:41
· 6 commits to master since this release

Fixed: two sites on one account could share each other's cached data

This is the important one, and it could take a site down.

Every Hostney account gets one Redis or Memcached instance, shared by every
domain on it. Each site is meant to keep its entries under its own key prefix.
That prefix was derived from the WordPress database table prefix and nothing
else — so two installations on the same account both using the default wp_
produced the same prefix and shared every key.

The failure looks like nothing at all: a blank white page, HTTP 200, and not one
line in any error log. The second site reads the first site's cached
alloptions, so template and stylesheet name a theme it does not have, the
template loader finds no file to include, and WordPress returns an empty
response. Nothing failed from PHP's point of view, so nothing was written to a
log. Deactivating the plugin removes the drop-in, options come from the database
again, and the site comes back — which makes the plugin look like the cause
rather than the collision.

Cache keys are now namespaced by database name, install path and table prefix.
WP_CACHE_KEY_SALT is honoured ahead of all of it, for installations that
deliberately want to share a cache.

Present in every release from 1.2.0 through 1.2.2.

Upgrading empties the object cache on affected sites. Entries written under
the colliding prefix cannot be trusted and must not be read back, so they are
abandoned rather than reused. Sites rebuild over the next few requests; there is
nothing to do.

Flushing is now scoped to a single site

Flushing emptied the whole instance, so every other site on the account lost its
cache at the same time — no warning, and nothing to tell those owners why their
site suddenly got slower. Installing or removing the drop-in did the same thing.

  • Flush this site is the new default and clears only this site's entries.
  • Flush all sites on this account is still there, behind a confirmation that
    names the other sites it is about to affect.
  • Installing the drop-in, removing it, and deactivating the plugin are all
    scoped the same way.
  • Deactivating now also clears this site's entries and removes its registry
    record, so nothing is left stranded in the shared instance.

New: Account keyspace

A panel showing how many cache entries each site on the account is holding, and
how many belong to no site at all — usually left behind by a domain that was
removed.

The key prefix is a one-way hash, so a site can work out its own and never a
neighbour's. Sites now record themselves in a small account-level registry,
which is what makes both the breakdown and the "this will also clear" warning
possible at all.

The breakdown reads every key in the instance, so it runs only when you ask for
it and never on page load.

Page caching and the purge endpoint are checked separately

The plugin page rendered both the "Page caching" and "Purge endpoint" rows from a
single test of the purge endpoint. Any address that caches without a purge
location, or does not cache at all, was reported as "Page caching: not detected"
— untrue, and the row people act on.

Each row now has its own check, and there are three outcomes rather than two:

  • cached and purgeable — fine
  • cached but not purgeable — genuinely broken, and now says so specifically
  • neither — an address that does not cache, such as a preview URL. Reported as
    normal rather than as a fault, and "Purge all cache" is no longer offered
    where it cannot work.

Redis and Memcached

Per-site flushing and the keyspace breakdown need Redis. Memcached has no way to
look up keys by prefix, so it offers only the account-wide flush and says so on
the page.

Key isolation — the fix at the top of this list — works on both engines.