Page MenuHomePhabricator

Implement a read-through cache layer
Closed, ResolvedPublic

Description

I think we're nearing a point where we'll get meaningful benefits out of having better caching available. In particular, I'd like to cache these frequently-executed, highly dirtyable queries:

  • Differential, Maniphest and Audit counts on the home page.
  • Notification and message counts.
  • User profile picture URIs.
  • User calendar status.

And possibly move this stuff to cache to make it more efficient to bulk load:

  • User session information.
  • User preferences.

We have most of the basics for this, but caching is currently "cache-aside" rather than "read-through", and we don't actively dirty keys. So this likely reduces to:

  • Provide general-purpose read-through infrastructure.
  • Provide general-purpose cache dirtying infrastructure.
  • Implement some caches.

Related Objects

Event Timeline

epriestley raised the priority of this task from to Normal.
epriestley updated the task description. (Show Details)
epriestley added a project: Performance.
epriestley added a subscriber: epriestley.

Quite possibly we should just denormalize profileImageURI and calendarStatus + calendarStatusTTL onto PhabricatorUser, since we almost always need those anyway and mixing real object queries with a read-through cache isn't a great v0 feature.

Profile images always have public visibility.

In the future, calendar status might be the result of an event the viewer does not have permission to see, but it still seems reasonable/expected to me for the actual busy/away status to be public, even if the event itself is not.

I'm going to tackle profile pictures first. I think it makes sense to denormalize them onto PhabricatorUser, not do them as a separate cache hit, because we almost always need them and they're very easy to dirty. We have some related technical debt which I'm going to try to clear first:

D12821 creates a bit of a problem: the CSS will expect 100x100 images, but all old profile images will be 50x50.

If we put a 50x50 image in a 100x100 CSS slot, it resizes into a tiny image 1/4th the size in the corner.

Some approaches I can come up with:

  1. Test for size and write out different CSS.
  2. Migrate all profile, project, and Conpherence images (roughly, they'd all be scaled up to 2x).
  3. Throw out all profile, project and Conpherence images (users would have to go reset them).
  4. Do nothing and let everything go goofy.
  5. Maybe we can do background-size: 100%?

I don't want to do (1) because of technical complexity.
I don't want to do (3) or (4) because I think they're really bad UX.

(2) is OK but is a long, error-prone migration for big installs.

(5) is the most promising but I'm not sure it will work properly.

So I'm going to see about (5) first, and we're probably stuck with (2) otherwise.

Oh, it doesn't actually create any peril until we try to use images larger than 50x50px (I was confusing it with some other unrelated issues), but I think it's still better to fix it now. It looks like using 100% works fine.

Or, more specifically:

If we put a 50x50 image in a 100x100 CSS slot, it resizes into a tiny image 1/4th the size in the corner.

This doesn't happen.

Oh, it doesn't actually create any peril until

This never creates any peril.

┬─┬ノ( º _ ºノ)

epriestley closed subtask Restricted Maniphest Task as Resolved.May 13 2015, 6:44 PM

There's nothing particularly actionable remaining here, although we'll always have more things to cache.