Uploaded image for project: 'Sakai'
  1. Sakai
  2. SAK-38636

Rewrite MemoryService APIs to allow pluggable caching (JSR-107)



    • Type: Bug
    • Status: CLOSED
    • Priority: Critical
    • Resolution: Fixed
    • Affects Version/s: 2.9.x
    • Fix Version/s: 10.0, 11.0
    • Component/s: Kernel
    • Labels:
    • 10 status:
    • Previous Issue Keys:


      Goal here is to remove direct bindings to Ehcache from the code so that other caching mechanisms can be swapped around under the covers. This means:

      • Remove all ehcache defs from spring configs
      • Remove ehcachemanager from central spring config
      • Move Ehcache based impl so it is not always deployed and can be replaced (it will remain the default implementation for now though)
      • Ensure all caches can be controlled via Sakai properties settings (since that will be the only way)

      BasicMemoryService currently uses Ehcache directly.
      This is a ticket to rewrite Sakai's MemoryService to allow pluggable caching implementations.
      Maybe we change our MemoryService to use JCache (JSR 107) and then single nodes can use ehcache-jcache and clusters can use hazelcast-jcache?

      We want to get this done before Sakai 10

      The multiref cache is meant to be a way to automatically handle the case where there is a cache full of entries which are linked to another single cache entry that contains a set of cache keys. When one of the single entries expires then it should also expire the linked set or vice versa. The way this is implemented, the set of keys are stored in the cache object on each server so it is not cluster safe and should no longer be used. I have deprecated it to make this clear.
      It still works the way it used to but it should simply be rewritten to handle this special case using 2 caches.
      Used in BaseAliasService.java and SakaiSecurity.java
      See KNL-1230 for removing this

      CACHE LOADER (CacheRefresher):
      This is simply a cache miss loader (also known as a blocking cache listener or cache warmer). This defines a kind of listener method which will be called whenever a cache miss occurs. In other words, if the cache is asked to retrieve an object by a key which does not exist in the cache then this method will be called if defined for that cache. Then the returned value will be returned from the lookup (or a null if no new value was found) and
      also inserted into the cache (unless the value was null).
      Similar to https://github.com/jsr107/jsr107spec/blob/master/src/main/java/javax/cache/integration/CacheLoader.java from the JSR-107 specification.
      See KNL-1226 but this functionality is broken in Sakai trunk and 2.9 (at least)

      The caching pattern (which is optionally configured when a cache is created) was meant to be a way to automatically remove entries in a cache when a change event occurs which matches the start of the pattern. In practice, this means the ref from the Event is checked against the pattern and if the ref startsWith the same chars then the cache entry that has a key matching that Event ref will be removed from the cache.
      This is probably better handled in each service using the cache (and in some cases it is also handled in the service). For now, I am marking the pattern as deprecated but keeping the functionality in place.
      See KNL-1229 for removing this

      The existing MemCache impl (DerivedCache is the listener API) uses Observers (which are local to one server) to notify the cache listeners that something has changed. This won't work across a cluster. The way the DerivedCache API works it only knows about put (add but not update) and remove and clear events (so no info about expires) and ONLY on the current server.
      I am going to leave the current stuff in place in the MemCache but then rewrite the Ehcache based one to only use the supported events that it understands.
      I removed the DerivedCache (and all uses of it) because it does NOT align with the actions in the JSR-107 cache listeners notifications. I have added in a new JSR-107 derived interface called CacheEventListener to replace it.

      JSR-107 deals with CacheEntryEvent.
      CacheEntryEvent(Cache source, EventType eventType) - sometimes has oldValue
      void onCreated(Iterable<CacheEntryEvent<? extends K, ? extends V>> events)
      void onExpired(Iterable<CacheEntryEvent<? extends K, ? extends V>> events)
      void onRemoved(Iterable<CacheEntryEvent<? extends K, ? extends V>> events)
      void onUpdated(Iterable<CacheEntryEvent<? extends K, ? extends V>> events)

        Gliffy Diagrams



              Issue Links



                  aaronz Aaron Zeckoski (Inactive)
                  ottenhoff Sam Ottenhoff
                  0 Vote for this issue
                  7 Start watching this issue



                      Git Integration