-
Notifications
You must be signed in to change notification settings - Fork 4
HasFullTableCache
HasFullTableCache
is used for a few ORM classes where the best thing for performance is for each application server to keep an entire database table in memory. Individual item lookups are delegated to the in-memory cache rather than going to the database. Some of the ORM classes that implement HasFullTableCache
are:
- Admin
- AdminRole
- Collection
- ConfigurationSetting
- DataSource
- DeliveryMechanism
- ExternalIntegration
- Genre
- Library
These classes have two things in common: there's a relatively small number of items in the database table, and the database changes very rarely.
Of course, when the data does change, we run into the problem of cache invalidation, one of the classic "hard problems" of computer science. Multiple application servers may keep caches of the same data. When one of those servers changes the data, all of them must know to invalidate their caches.
That's why the circulation manager checks at the beginning of each request whether the cache needs to be invalidated. We track that information in a special row in the timestamps
table (which does not implement HasFullTableCache
) where the service
field is set to the special value Site Configuration Changed
.
Whenever a change is made to one of the tables that implements HasFullTableCache
, a listener fires and calls the function site_configuration_has_changed
. This function uses a raw SQL command to update the timestamps
table with the current date. Any HasFullTableCache
s populated before that date are now invalid. We don't try to be clever about it; it's not worth it. Any change to any of these tables invalidates every single HasFullTableCache
.
But how does the circulation manager detect that this timestamp has changed? A method called Configuration.site_configuration_last_update
retrieves this value from the database. The circulation manager's controller class defines a method called reload_settings_if_changed
which checks that value and invalidates all of the HasFullTableCache
s if necessary. This method is called by library_for_request
and library_through_external_loan_identifier
.
This means reload_settings_if_changed
will be called very early on when processing basically any incoming request.
If you run SQL directly against the database, as opposed to using the ORM, the SQLAlchemy listeners won't trigger and the timestamp won't be updated. This can cause problems if you do this while application servers are running.
Run this SQL to update the timestamp manually:
UPDATE timestamps SET finish=now() WHERE service='Site Configuration Changed' AND collection_id IS NULL;
This will cause all app servers to reload their full-table caches on the next request.