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

Sakai getAll caching is dangerous and cannot be supported by the Java cache standard (JSR-107)

    XMLWordPrintable

    Details

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

      Description

      Sakai includes some methods in the Cache API which retrieve all the possible values in a cache. This is not supported by distributed caches because the nature of the cache is that it is not actually possible to determine what all the elements might be since they are spread across numerous nodes. Attempting to get them all would be very costly to the cache servers and would also cause problems with the refreshes since it would constantly make the entire cache appear active. This would basically guarantee a cache slam whenever the cache reaches the max TTL as all elements would flush at the same time and be reloaded.

      Generally speaking, this use of caching means that Sakai cannot scale well in certain areas and we cannot go to a fully distributed cache (or a cache library that adheres to the standard and does not support this behavior).

      This also requires there be extra cache functionality because the cache has to be marked to indicate it contains all the possible cache entries. It also has to be put into a "pause" state while loading all entries to avoid generating events.

      For example:
      kernel/kernel-impl/src/main/java/org/sakaiproject/event/impl/BaseNotificationService.java
      List getNotifications(String function)

      // if the cache is complete, use it
      if (m_cache.isComplete())

      { notifications = m_cache.getAll(function); }

      // otherwise get all the notifications from storage
      else
      {
      // Note: while we are getting from storage, storage might change. These can be processed
      // after we get the storage entries, and put them in the cache, and mark the cache complete.
      // -ggolden
      synchronized (m_cache)
      {
      // if we were waiting and it's now complete...
      if (m_cache.isComplete())

      { notifications = m_cache.getAll(function); }

      else
      {
      // save up any events to the cache until we get past this load
      m_cache.holdEvents();

      // get them all for caching
      List all = m_storage.getAll();

      // update the cache, and mark it complete
      for (int i = 0; i < all.size(); i++)

      { Notification notification = (Notification) all.get(i); m_cache.put(notification); }

      m_cache.setComplete();

      // get those for just this function
      notifications = m_cache.getAll(function);

      // now we are complete, process any cached events
      m_cache.processEvents();
      }
      }
      }

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  aaronz Aaron Zeckoski (Inactive)
                  Reporter:
                  aaronz Aaron Zeckoski (Inactive)
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  0 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved:

                    Git Source Code