Cache review request counts for quick lookup in the dashboard.

Review Request #1848 — Created Oct. 19, 2010 and submitted — Latest diff uploaded


Review Board


The Dashboard is one of our most expensive yet most frequently visited pages, largely due to the number of expensive queries happening on each load. Every page load would have at least 6 queries for counts on the sidebar, possibly more depending on watched groups and such. As a database grows, this gets much slower.

We now cache the counts in the database. The Profile model now stores counts for starred review requests, outgoing pending review requests, all outgoing review requests, direct pending incoming review requests ("To Me"), and total pending incoming review requests. The Group model stores a count of incoming pending review requests.

These counts are updated when saving a ReviewRequest (specifically, when creating, publishing, closing, or reopening one) and when starring/unstarring review requests.

This reduces the query count on the dashboard by 7 queries.

It also converts the shipit_count field to use the new CounterField, since we're doing the same thing there, and consistency is good. Given that Counterfield is really just an IntegerField, this required no evolution.

There are unit tests that attempt to cover all the cases where we may end up updating these counts. It's possible that we may find bugs where the counts get out of sync. Fortunately, this would be nothing more than an annoyance on the sidebar, and we could provide a way to recompute the counts for users.
I've only been able to test this on my small SQLite setup, which is already not all that slow on the dashboard. However, I have verified that we do reduce by 7 queries, and we know that these can take longer on a significantly larger database.

The unit tests all pass.

All the hand testing I've done have paid off. I've created, starred, unstarred, discarded, submitted, and reopened review requests and saw the counts I expected.