Project

General

Profile

Actions

Feature #8

open

Add some sort of caching for config from DB settings

Added by Lance Edgar over 2 years ago. Updated about 2 years ago.

Status:
New
Priority:
Low
Assignee:
Start date:
07/31/2022
Due date:
% Done:

0%

Estimated time:

Description

I've long been aware of inefficiencies caused by constant querying of the setting table for real-time config values. It was originally noticed because of the sheer number of queries required e.g. for a single page load in the web app.

Accordingly, I've long intended to add some sort of caching mechanism to cut down on the number of queries. However there is a new problem, illustrated by #6 and #7: Not only are there too many queries, but they require too many DB sessions!

So the caching mechanism needs to allow for:

  • no change in calling code, e.g. config.get('foo', 'bar') should "just work"
  • caller should get "current value" without need for DB session/query
  • changes to settings in DB must take effect "immediately" (more or less)

I think two approaches make sense:

Basic / Native Caching

First, the RattailConfig class should implement a basic caching mechanism. This should keep track of values already fetched from the DB, and when each was fetched. If an already-fetched value is requested from caller, and it was fetched "recently" enough (e.g. within last 30 seconds?) then the cached value is returned to caller as-is. If the fetch was not recent enough, it is re-fetched via DB query.

This has the advantage of being built-in to Rattail and therefore can work out of the box with no setup needed. May still want to allow config to disable the caching (perhaps it should even be off by default?), as well as config to determine cache expiry timeout, i.e. TTL for the cached values.

But it has the disadvantage of still tying up DB sessions and running queries semi-regularly. The cutoff of 30 seconds is striking a balance: We don't want to keep running queries if the same values are requested frequently; however the values may be changed by admin user at any time, so it's not safe to "always" return the same value from cache. It's hoped that 30 seconds is often enough to reflect actual changes "quickly" but infrequent enough to help somewhat with session/query overhead.

Beaker Caching

Ultimately I think the best fix here is to split out the config caching to its own "service". Since the web app already uses Beaker (for user sessions) it probably makes sense to use that here as well, since it provides a Caching system with support for multiple back-ends (e.g. file, memcached, redis).

Assuming a "normal" back-end (e.g. file, memcached, redis) then I believe all running Rattail apps could effectively leverage the same cache. For a given app, this would mean not only that it need run fewer queries to fetch settings, but in fact (potentially) zero queries.

Depending on the desired back-end, this may require some more setup. But hopefully a basic file-based cache would require only turning on a single config flag; i.e. the default file path for cache storage could be determined automatically (or overridden via config).

One gotcha here is the question of when/how to "invalidate" the cache for a given setting. This is especially important if multiple apps are leveraging a single cache. Consider:

  • an admin user can modify Raw Settings via the web app
  • some apps will auto-write settings to DB, e.g. datasync lastrun times

Anytime a setting is modified in the DB, the cache system needs to know about it so that it will re-fetch the new value when it is next requested by a caller.

I believe that since settings are usually written via dedicated function, we can add some hook to invalidate cache for the setting which is being written. But this will need closer attention when I get to that point.


Related issues 3 (1 open2 closed)

Related to Rattail - Bug #6: Datasync error: QueuePool limit of size 5 overflow 10 reached, connection timed out, timeout 30ClosedLance Edgar07/26/2022

Actions
Related to Rattail - Bug #7: Datasync error: remaining connection slots are reserved for non-replication superuser connectionsClosedLance Edgar07/26/2022

Actions
Related to Rattail - Feature #9: Split out config to separate package?In ProgressLance Edgar08/06/2022

Actions
Actions

Also available in: Atom PDF