-
Bug
-
Resolution: Fixed
-
Minor
-
3.0.6, 3.1.1
-
MOODLE_30_STABLE, MOODLE_31_STABLE
-
MOODLE_30_STABLE, MOODLE_31_STABLE
-
- Unit tests verify all of the changes here.
This is internal to the Moodle caching API - externally everything appears correct, but it leads to potential performance drawbacks, and unexpected behaviors.
Lets preface this by saying you have the following things:
A cache that uses static acceleration (plus a backing cache)
You are using a class myCachable that extends cacheable_object to store data in the cache
First I start out with a completely empty cache. I try to get() and fail, so I create my myCachable instance, and call set() with it. Inside the caching API encapsulates that in a cache_cached_object object, and then proceeds to store it in the static cache (just as an object) and the backing cache. Any additional calls to get() during this page load will pull the cache_cached_object out of the static cache, calling restore_object().
Now, on the next page load, when I call get(), the static cache misses, but the backing cache hits, returning a cache_cached_object. Inside get(), the cache_cached_object is restored with restore_object() back into a myCachable, then set in the static cache. But now the static cache contains an instance of myCachable, not a cache_cached_object.
This causes a problem, because static_acceleration_set() treats cache_cached_object's in a special way - storing it as a plain object, then has the object restore itself with wake_from_cache(). When you pass it an object other than a cache_cached_object, it serializes it, and then on the flip side unserialize it, and never 'wakes' it.
This creates a few problems:
- Serialize/unserialize is pretty slow, and a well implemented cacheable_object could be faster
- The cacheable_object may not be serializable (at least not correctly)
- The cacheable_object may rely on wake_from_cache() being called to do special behaviors
The fix should be pretty strait forward - when we fetch a cache_cached_object from the backing cache, we should set that into the static cache, not the reconstituted object.