This sounds really useful.

Definitely a +1

On Tue, Jul 8, 2008 at 11:32 AM, Drew Wills <[EMAIL PROTECTED]> wrote:

> Hey folks,
>
> I'm working at JHU, and we've put together an enhancement to DLM:  the
> ability to store users' layouts in a standard, portal managed cache.
> Currently users' layouts are stored (at least in DLM) as a member
> variable on each user's LayoutManager instance.
>
> This situation means that:
>   - User layouts never change until (1) the user makes a manual change,
> or (2) the user logs in again
>   - There's no way to manage in-memory layout data administratively
>
> With this enhancement, you'd be able to:
>   - specify that user layouts should expire and be rebuilt, say, 15 min
> after creation or after 10 min of "idle" time (i.e. not used for 10 min)
>   - specify that no more than, say, 500 layouts should be held in
> memory at one time
>   - use JMX to "clear" (drop) all the layouts in a running instance of
> uPortal
>   - write Java tools that intelligently invalidate individual layouts
> (or all layouts) when certain portal events happen
>
> The changes are relatively small & encapsulated, so they're unlikely to
> "break" existing features or even custom Java tech that integrates with
> DLM.
>
> I'm attaching a .patch that shows the delta.
>
> Please share thoughts on whether this enhancement is desirable or even
> acceptable.  If there's interest, I'll create the JIRA etc.
>
> drew wills
>
>
>
> --
> You are currently subscribed to [email protected] as:
> [EMAIL PROTECTED]
> To unsubscribe, change settings or access archives, see
> http://www.ja-sig.org/wiki/display/JSG/uportal-dev
> Index:
> uportal-impl/src/main/java/org/jasig/portal/layout/dlm/DistributedLayoutManager.java
> ===================================================================
> ---
> uportal-impl/src/main/java/org/jasig/portal/layout/dlm/DistributedLayoutManager.java
>        (revision 6156)
> +++
> uportal-impl/src/main/java/org/jasig/portal/layout/dlm/DistributedLayoutManager.java
>        (working copy)
> @@ -90,7 +90,7 @@
>      */
>     static final String FOLDER_LABEL_POLICY = "FolderLabelPolicy";
>
> -    protected Document userLayoutDocument=null;
> +    private final Map<String,Document> layoutCache =
> LayoutCachingService.getInstance().getLayoutCache();
>
>     protected static Random rnd=new Random();
>     protected String cacheKey="initialKey";
> @@ -226,7 +226,8 @@
>     }
>
>     private void setUserLayoutDOM(Document doc) {
> -        this.userLayoutDocument = doc;
> +
> +       layoutCache.put(owner.getUserName(), doc);
>         this.updateCacheKey();
>
>         // determine if this is a layout fragment by looking at the root
> node
> @@ -243,6 +244,7 @@
>         if (labelPolicy != null) {
>             labelPolicy.coordinateFolderLabels(owner.getID(),
> isFragmentOwner, doc);
>         }
> +
>     }
>     private int domRequests = 0;
>
> @@ -261,7 +263,7 @@
>             {
>                 LOG.debug("domRequest: " + (domRequests++));
>             }
> -            Document userLayoutDocument = this.userLayoutDocument;
> +            Document userLayoutDocument =
> layoutCache.get(owner.getUserName());
>             if ( null == userLayoutDocument )
>             {
>                 IUserLayoutStore layoutStore = getLayoutStore();
> @@ -407,7 +409,7 @@
>         try {
>             //Clear the loaded document first if this is a forced reload
>             if (reload) {
> -                this.userLayoutDocument = null;
> +               layoutCache.remove(owner.getUserName());
>             }
>
>             uli=getUserLayoutDOM();
> @@ -1507,7 +1509,7 @@
>         }
>         //this.markedUserLayout=null;
>         this.updateCacheKey();
> -        this.userLayoutDocument=doc;
> +        layoutCache.put(owner.getUserName(), doc);
>     }
>
>     /* Returns the ID attribute of the root folder of the layout. This
> folder
> @@ -1689,7 +1691,7 @@
>             // so we need to refresh our local copy of their layout
>             if (person == owner)
>             {
> -                this.userLayoutDocument = null;
> +               layoutCache.remove(owner.getUserName());
>                 updateCacheKey();
>                 getUserLayoutDOM();
>             }
> Index:
> uportal-impl/src/main/java/org/jasig/portal/layout/dlm/LayoutCachingService.java
> ===================================================================
> ---
> uportal-impl/src/main/java/org/jasig/portal/layout/dlm/LayoutCachingService.java
>    (revision 0)
> +++
> uportal-impl/src/main/java/org/jasig/portal/layout/dlm/LayoutCachingService.java
>    (revision 0)
> @@ -0,0 +1,120 @@
> +/**
> + * Copyright 2008 The JA-SIG Collaborative.  All rights reserved.
> + * See license distributed with this file and
> + * available online at http://www.uportal.org/license.html
> + */
> +
> +package org.jasig.portal.layout.dlm;
> +
> +import java.util.Map;
> +import org.w3c.dom.Document;
> +
> +import org.springframework.beans.factory.annotation.Required;
> +
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +import org.jasig.portal.utils.cache.CacheFactory;
> +
> +/**
> + * Provides caching services for layouts contained in
> + * <code>DistributedLayoutManager</code> instances.  This class is an
> old-school
> + * singleton whose backing-map is "injected" by a spring context at
> startup.
> + */
> +public final class LayoutCachingService {
> +
> +       /**
> +        * The name of the cache used by <code>LayoutCachingService</code>.
>  A cache
> +        * of this name must be defined within uPortal's
> <code>'cacheFactory'</code>
> +        * bean.
> +        */
> +       private static final String CACHE_NAME =
> "org.jasig.portal.layout.dlm.LAYOUT_CACHE";
> +
> +       /**
> +        * Single(ton) instance of this class.
> +        */
> +       private static LayoutCachingService instance = null;
> +
> +       /**
> +        * "Injected" at startup by the bean container.  This object is
> typically
> +        * defined as the bean with id='cacheFactory' in cacheContext.xml.
> +        */
> +       private CacheFactory cacheFactory = null;
> +
> +    private final Log log = LogFactory.getLog(LayoutCachingService.class);
> +
> +       /*
> +        * Public API.
> +        */
> +
> +    /**
> +     * Accessor method or the single(ton) instance of this class.
> +     */
> +    public static LayoutCachingService getInstance() {
> +
> +               if (instance == null) {
> +                       init();
> +               }
> +
> +               return instance;
> +
> +       }
> +
> +    /**
> +     * Called by the spring IoC container at startup.
> +     *
> +     * @param cf Ordinarily 'cacheFactory' bean defined in
> cacheContext.xml
> +     */
> +       @Required
> +       public void setCacheFactory(CacheFactory cf) {
> +
> +               // Assertions.
> +               if (cf == null) {
> +                       String msg = "Argument 'cpf [CacheFactory]' cannot
> be null.";
> +                       throw new IllegalArgumentException(msg);
> +               }
> +
> +               log.debug("INITIALIZING:  Setting cacheFactory.");
> +
> +               this.cacheFactory = cf;
> +
> +       }
> +
> +       /**
> +        * Provides clients of <code>LayoutCachingService</code> with
> access to the
> +        * layout cache.
> +        *
> +        * @return A <code>Map</code> of cached layouts.
> +        */
> +       public Map<String,Document> getLayoutCache() {
> +               return cacheFactory.getCache(CACHE_NAME);
> +       }
> +
> +       /*
> +        * Implementation.
> +        */
> +
> +       /**
> +        * Private as per classic Singleton pattern.
> +        */
> +       private LayoutCachingService() {
> +               log.debug("INITIALIZING:  Constructing.");
> +       }
> +
> +       /**
> +        * Method that creates the single(ton) instance of
> +        * <code>LayoutCachingService</code>, synchronized to be sure it
> only
> +        * happens once.
> +        */
> +       private static synchronized void init() {
> +
> +               // Make sure we only create one instance...
> +               if (instance != null) {
> +                       // Must have invoked getInstance() w/ 2 threads.
> +                       return;
> +               }
> +
> +               instance = new LayoutCachingService();
> +
> +       }
> +
> +}
> Index: uportal-impl/src/main/resources/properties/contexts/cacheContext.xml
> ===================================================================
> --- uportal-impl/src/main/resources/properties/contexts/cacheContext.xml
>      (revision 6156)
> +++ uportal-impl/src/main/resources/properties/contexts/cacheContext.xml
>      (working copy)
> @@ -43,4 +43,22 @@
>         <property name="cacheManagerName" value="uPortal.cacheManager" />
>         <property name="configLocation"
> value="classpath:/properties/ehcache.xml" />
>     </bean>
> -</beans>
> \ No newline at end of file
> +
> +    <!--
> +     | Service used by DLM to cache Layouts.
> +     +-->
> +    <bean id="layoutCachingService"
> class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
> +        <property name="targetClass"
> value="org.jasig.portal.layout.dlm.LayoutCachingService" />
> +        <property name="targetMethod" value="getInstance" />
> +    </bean>
> +    <bean
> class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
> +        <property name="targetObject" ref="layoutCachingService" />
> +        <property name="targetMethod" value="setCacheFactory" />
> +        <property name="arguments">
> +            <list>
> +                <ref bean="cacheFactory"/>
> +            </list>
> +        </property>
> +    </bean>
> +
> +</beans>
> Index: uportal-impl/src/main/resources/properties/ehcache.xml
> ===================================================================
> --- uportal-impl/src/main/resources/properties/ehcache.xml      (revision
> 6156)
> +++ uportal-impl/src/main/resources/properties/ehcache.xml      (working
> copy)
> @@ -81,6 +81,10 @@
>                 replicateRemovals=true "/>
>     </cache>
>
> +    <cache name="org.jasig.portal.layout.dlm.LAYOUT_CACHE"
> +        eternal="false" maxElementsInMemory="250" overflowToDisk="false"
> diskPersistent="false"
> +        timeToIdleSeconds="0" timeToLiveSeconds="0"
> memoryStoreEvictionPolicy="LRU" />
> +
>     <!-- uPortal IBasicEntity Caches -->
>
>     <cache name="org.jasig.portal.ChannelDefinition"
>
>

-- 
You are currently subscribed to [email protected] as: [EMAIL 
PROTECTED]
To unsubscribe, change settings or access archives, see 
http://www.ja-sig.org/wiki/display/JSG/uportal-dev

Reply via email to