Edgewall Software

Changes between Initial Version and Version 1 of TracDev/Proposals/CacheInvalidation


Ignore:
Timestamp:
Mar 6, 2009, 3:26:34 PM (15 years ago)
Author:
Christian Boos
Comment:

the case for cache invalidation

Legend:

Unmodified
Added
Removed
Modified
  • TracDev/Proposals/CacheInvalidation

    v1 v1  
     1= The problem of cache invalidation =
     2
     3== Problem ==
     4Trac uses various caches at the component level, in order to speed-up costly tasks. Some examples are the recent addition of ticket fields cache (#6436), others are the InterMapTxt cache, the user permission cache, the oldest example being the Wiki page cache.
     5
     6Those cache are held at the level of `Component` instances. For a given class, there's one such instance per environment in any given server process. The first thing to take into account here is that those caches must be safely accessed and modified when accessed by concurrent threads (in multi-threaded web front ends, that is). That's not a big deal, and I think it's already handled appropriately.
     7
     8But due to the always possible concurrent access at the underlying database level by multiple processes, there's also a need to maintain a consistency and up-to-date status of those caches across all processes involved. Otherwise, you might do a change by the way of one request and the next request (even the GET following a redirect after your POST!) might be handled by a different server process which has a different "view" of the application state, and you end up confused at best, filing a bug on t.e.o at worst ;-)
     9
     10This doesn't even have to imply a multi-process server setup, as all what is needed is e.g. a modification of the database done using trac-admin.
     11
     12== Current Situation ==
     13So the current solution to the above problem is to use some kind of global reset mechanism, which will not only invalidate the caches, but simply "throw away" all the `Component` instances of the environment that has been globally reset. That reset happens by the way of a simulated change on the TracIni file, triggered by a call to `self.config.touch()` from a component instance. The next time an environment instance is retrieved, the old environment instance is found to be out of date and a new one will be created (see `trac.env.open_environment`). Consequently, new Component instances will be created as well, and the caches will be repopulated as needed.
     14
     15Pros:
     16 - it works well ;-)
     17
     18Cons:
     19 - it's a bit costly - though I've no numbers on that, it's easy to imagine that if this full reset happens too frequently, then the benefits from the caches will simply disappears. In the past, when the reset rate was abnormally high due to some bug, the performance impact was very perceptible.
     20 - it's all or nothing - the more we rely on this mechanism for different caches, the more we'll aggravate the above situation. Ideally, invalidating one cache should not force all the other caches to be reset.
     21
     22
     23
     24