Uploaded image for project: 'MyFaces Trinidad'
  1. MyFaces Trinidad
  2. TRINIDAD-2515

Avoid caching skins from external SkinProviders and make LRU cache concurrent

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 2.1.0-core
    • None
    • Skinning
    • None

    Description

      Problem statement:
      SkinProvider SPI allows creation of external skin repositories and plug it into trinidad skin framework. Skin framework should allow such skins to be managed (created, cached, destroyed) by the SkinProvider. Currently this is not happening.

      Internal problem description:
      When user requests a Skin, skin framework creates a StyleProvider for it. This StyleProvider is cached at application level and reused for subsequent requests for the same Skin. Since the StyleProvider contains the Skin, it effectively caches the Skin also.

      Solution:
      Don't cache StyleProvider associated with Skins served from external SkinProviders. For achieveing this introduce isCacheable API on SkinImpl and implement it in SkinExtension:

        /**
         * Used by SkinStyleProvider to decide whether to cache the StyleProvider or not.
         * @return true if skin is internal to the framework.
         */
        public abstract boolean isCacheable();
      
      

      In SkinExtension introduce overloaded constructor for handling internal Skin creation and external Skin creation (through SkinFactory.createSkin)

        /**
         * Creates SkinExtension from SkinMetadata and base Skin
         * This constructor is used for creating skins for external SkinProvider implementations.
         * We keep skins thus created as not-cacheable.
         * @see org.apache.myfaces.trinidadinternal.skin.SkinFactoryImpl
         * @param baseSkin
         * @param skinMetadata
         */
        public SkinExtension(Skin baseSkin, SkinMetadata skinMetadata)
        {
          this(baseSkin, skinMetadata, false);
        }
      
        /**
         * Creates SkinExtension from SkinMetadata, base Skin and cacheability
         * This constructor is used only for INTERNAL skins
         * @see org.apache.myfaces.trinidadinternal.skin.provider.TrinidadSkinProvider
         * @param baseSkin
         * @param skinMetadata
         */
        public SkinExtension(Skin baseSkin, SkinMetadata skinMetadata, boolean isCacheable)
        {
          // existing code:
          // read values from skinMetadata and set
          _isCacheable = isCacheable;
        }
      

      Check SkinImpl.isCacheable() before caching the StyleProvider.

      For solving the concurrency issue in LRU cache used for caching StyleProviders, introduce new CopyOnWriteArrayMap and use it.

      For testing add SkinProvider test cases, CopyOnWriteArrayMap test cases.

      Attachments

        1. test-skin-and-images.zip
          134 kB
          Anand V Nath
        2. jira-2515-test-order-fix.patch
          1 kB
          Anand V Nath
        3. jira-2515.patch
          150 kB
          Anand V Nath

        Activity

          People

            Unassigned Unassigned
            anand.v.nath@oracle.com Anand V Nath
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: