[jboss-user] [JBoss Cache: Core Edition] - Option to remove persistent data is a valid use case

cacheuser do-not-reply at jboss.com
Tue Jul 29 16:08:19 EDT 2008


A Eviction policy option to be able to remove persistent data is valid use case that the JBoss Cahe does not support right. For example, we are storing data that we get by making a webservice call to other vendor, we have contract with to be able to store the data for no longer than a certain number of days. The current LRUPolicy supports maxAge that can be used to get the data out of the memory and we use persistent (JBDCCacheLoader) store to the data, ones that data is persistent store we dont have a way to identify and get rid of the data after x number of days. It is easy for the Cache to clean up the data that it creates and I modified the LRUPolicy and LRUConfiguration as follows to. The modifications are in bold

  | /*
  |  * JBoss, the OpenSource J2EE webOS
  |  *
  |  * Distributable under LGPL license.
  |  * See terms of license at gnu.org.
  |  */
  | package org.jboss.cache.eviction;
  | 
  | import org.jboss.cache.config.ConfigurationException;
  | import org.jboss.cache.config.Dynamic;
  | 
  | /**
  |  * Configuration implementation for {@link LRUPolicy}.
  |  * <p/>
  |  * If configured via XML, expects the following:
  |  * <p/>
  |  * <pre>
  |  * <region name="/maxAgeTest/">
  |  *    <attribute name="maxNodes">10000</attribute>
  |  *    <attribute name="timeToLiveSeconds">8</attribute>
  |  *    <attribute name="maxAgeSeconds">10</attribute>
  |  * </region>
  |  * </pre>
  |  *
  |  * @author Daniel Huang (dhuang at jboss.org)
  |  * @version $Revision: 6252 $
  |  */
  | public class LRUConfiguration extends EvictionPolicyConfigBase
  | {
  |    /**
  |     * The serialVersionUID
  |     */
  |    private static final long serialVersionUID = -3426716488271559729L;
  | 
  |    @Dynamic
  |    @Deprecated
  |    private int timeToLiveSeconds;
  |    @Dynamic
  |    @Deprecated
  |    private int maxAgeSeconds;
  | 
  | 
  |    /** value expressed in millis*/
  |    @Dynamic
  |    private long timeToLive;
  | 
  |    /** value expressed in millis*/
  |    @Dynamic
  |    private long maxAge;
  |    
  |    /** if true, nodes that are past maxAge will be removed*/
  |    @Dynamic
  |    private boolean maxAgeRemove;   
  | 
  |    public LRUConfiguration()
  |    {
  |       super();
  |       // Force config of ttls
  |       setTimeToLive(-1);
  |    }
  | 
  |    public LRUConfiguration(long timeToLive, long maxAge)
  |    {
  |       super();
  |       setTimeToLive(timeToLive);
  |       setMaxAge(maxAge);
  |       setMaxAgeRemove(false);
  |    }
  | 
  |    @Override
  |    protected void setEvictionPolicyClassName()
  |    {
  |       setEvictionPolicyClass(LRUPolicy.class.getName());
  |    }
  | 
  |    /** value expressed in millis*/
  |    public long getTimeToLive()
  |    {
  |       return timeToLive;
  |    }
  | 
  |    /** value expressed in millis*/
  |    public void setTimeToLive(long timeToLive)
  |    {
  |       testImmutability("timeToLive");
  |       this.timeToLive = timeToLive;
  |       this.timeToLiveSeconds = (int)(timeToLive/1000);
  |    }
  | 
  |    /** value expressed in millis*/
  |    public long getMaxAge()
  |    {
  |       return maxAge;
  |    }
  | 
  |    /** value expressed in millis*/
  |    public void setMaxAge(long maxAge)
  |    {
  |       testImmutability("maxAge");
  |       this.maxAge = maxAge;
  |       this.maxAgeSeconds = (int) (maxAge/1000);
  |    }
  | 
  |    public boolean isMaxAgeRemove() 
  |    {
  | 		return maxAgeRemove;
  |    }
  |    
  |    public void setMaxAgeRemove(boolean maxAgeRemove) 
  |    {
  | 		this.maxAgeRemove = maxAgeRemove;
  |    }
  | 
  |    /**
  |     * use {@link #getTimeToLive()}
  |     * @return
  |     */
  |    @Deprecated
  |    public int getTimeToLiveSeconds()
  |    {
  |       return timeToLiveSeconds;
  |    }
  | 
  |    /**
  |     * Use {@link #setTimeToLive(long)}
  |     */
  |    @Deprecated
  |    public void setTimeToLiveSeconds(int timeToLiveSeconds)
  |    {
  |       testImmutability("timeToLiveSeconds");
  |       this.timeToLiveSeconds = timeToLiveSeconds;
  |       timeToLive = timeToLiveSeconds * 1000;
  |    }
  | 
  |    /**
  |     * Use {@link #getMaxAge()}
  |     * @deprecated 
  |     */
  |    @Deprecated
  |    public int getMaxAgeSeconds()
  |    {
  |       return maxAgeSeconds;
  |    }
  | 
  |    /**
  |     * Use {@link #getMaxAge()}
  |     * @param maxAgeSeconds
  |     */
  |    @Deprecated
  |    public void setMaxAgeSeconds(int maxAgeSeconds)
  |    {
  |       testImmutability("maxAgeSeconds");
  |       this.maxAgeSeconds = maxAgeSeconds;
  |       this.maxAge = maxAgeSeconds * 1000;
  |    }
  | 
  |    /**
  |     * Requires a positive timeToLive value or ConfigurationException
  |     * is thrown.
  |     */
  |    @Override
  |    public void validate() throws ConfigurationException
  |    {
  |       if (timeToLive < 0)
  |       {
  |          throw new ConfigurationException("timeToLive must be " +
  |                "configured to a value greater than or equal to 0 for " + getEvictionPolicyClass());
  |       }
  |    }
  | 
  | 
  |    public String toString()
  |    {
  |       return "LRUConfiguration{" +
  |             "timeToLiveSeconds=" + timeToLiveSeconds +
  |             ", timeToLive=" + timeToLive +
  |             ", maxAge=" + maxAge +
  |             '}';
  |    }
  | 
  |    public boolean equals(Object o)
  |    {
  |       if (this == o) return true;
  |       if (!(o instanceof LRUConfiguration)) return false;
  |       if (!super.equals(o)) return false;
  | 
  |       LRUConfiguration that = (LRUConfiguration) o;
  | 
  |       if (maxAge != that.maxAge) return false;
  |       if (maxAgeSeconds != that.maxAgeSeconds) return false;
  |       if (timeToLive != that.timeToLive) return false;
  |       if (timeToLiveSeconds != that.timeToLiveSeconds) return false;
  | 
  |       return true;
  |    }
  | 
  |    public int hashCode()
  |    {
  |       int result = super.hashCode();
  |       result = 31 * result + timeToLiveSeconds;
  |       result = 31 * result + maxAgeSeconds;
  |       result = 31 * result + (int) (timeToLive ^ (timeToLive >>> 32));
  |       result = 31 * result + (int) (maxAge ^ (maxAge >>> 32));
  |       return result;
  |    }
  | 
  |    @Override
  |    public void reset()
  |    {
  |       super.reset();
  |       setTimeToLive(-1);
  |    }
  | 
  |    @Override
  |    public LRUConfiguration clone() throws CloneNotSupportedException
  |    {
  |       return (LRUConfiguration) super.clone();
  |    }
  | 
  | }
  | 


  | /*
  |  * JBoss, the OpenSource J2EE webOS
  |  *
  |  * Distributable under LGPL license.
  |  * See terms of license at gnu.org.
  |  * Created on March 25 2003
  |  */
  | package org.jboss.cache.eviction;
  | 
  | import org.jboss.cache.CacheSPI;
  | import org.jboss.cache.Fqn;
  | import org.jboss.cache.RegionManager;
  | 
  | /**
  |  * Provider to provide eviction policy. This one is based on LRU algorithm that a user
  |  * can specify either maximum number of nodes or the idle time of a node to be evicted.
  |  *
  |  * @author Ben Wang 02-2004
  |  * @author Daniel Huang - dhuang at jboss.org
  |  * @version $Revision: 5730 $
  |  */
  | public class LRUPolicy extends BaseEvictionPolicy
  | {
  |    protected RegionManager regionManager_;
  | 
  |    protected EvictionAlgorithm algorithm;
  | 
  |    public LRUPolicy()
  |    {
  |       super();
  |       algorithm = new LRUAlgorithm();
  |    }
  | 
  |    public EvictionAlgorithm getEvictionAlgorithm()
  |    {
  |       return algorithm;
  |    }
  | 
  |    public void evict(Fqn fqn) throws Exception
  |    {
  | 	  if(((LRUAlgorithm)algorithm).getConfiguration().isMaxAgeRemove())
  | 		  cache_.removeNode(fqn);
  | 	  else
  | 		  cache_.evict(fqn, false);
  |    }
  | 
  |    public Class<LRUConfiguration> getEvictionConfigurationClass()
  |    {
  |       return LRUConfiguration.class;
  |    }
  | 
  |    @Override
  |    public void setCache(CacheSPI cache)
  |    {
  |       super.setCache(cache);
  |       regionManager_ = cache_.getRegionManager();
  |    }
  | }
  | 
  | 


  | <?xml version="1.0" encoding="UTF-8"?>
  | 
  | <!-- ===================================================================== -->
  | <!--                                                                       -->
  | <!--  Sample JBoss Cache Service Configuration                             -->
  | <!--                                                                       -->
  | <!-- ===================================================================== -->
  | 
  | <server>
  |    
  |    <!-- ==================================================================== -->
  |    <!-- Defines JBoss Cache configuration                                      -->
  |    <!-- ==================================================================== -->
  |    
  |   
  |  <mbean code="org.jboss.cache.jmx.CacheJmxWrapper"
  | 	          name="jboss.mycache:service=Cache">
  | 
  | 
  |   
  |       <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
  | 
  |       <!-- Lock parent before doing node additions/removes -->
  |       <attribute name="LockParentForChildInsertRemove">true</attribute>
  | 
  |       <!-- Valid modes are LOCAL (default)
  |                            REPL_ASYNC
  |                            REPL_SYNC
  |                            INVALIDATION_ASYNC
  |                            INVALIDATION_SYNC   -->
  |       <attribute name="CacheMode">LOCAL</attribute>
  | 
  |       <!-- Name of cluster. Needs to be the same for all JBoss Cache nodes in a
  |            cluster in order to find each other. 
  |       -->
  |       <attribute name="ClusterName">JBossCache-Cluster</attribute>
  | 
  |       <!-- JGroups protocol stack properties.
  |          ClusterConfig isn't used if the multiplexer is enabled above.
  |       -->
  |       <attribute name="ClusterConfig">
  |          <config>
  |             <!-- UDP: if you have a multihomed machine, set the bind_addr 
  |                  attribute to the appropriate NIC IP address -->
  |             <!-- UDP: On Windows machines, because of the media sense feature
  |                  being broken with multicast (even after disabling media sense)
  |                  set the loopback attribute to true -->
  |             <UDP mcast_addr="228.1.2.3" mcast_port="48866"
  |                  ip_ttl="64" ip_mcast="true"
  |                  mcast_send_buf_size="150000" mcast_recv_buf_size="80000"
  |                  ucast_send_buf_size="150000" ucast_recv_buf_size="80000"
  |                  loopback="false"/>
  |             <PING timeout="2000" num_initial_members="3"/>
  |             <MERGE2 min_interval="10000" max_interval="20000"/>
  |             <FD shun="true"/>
  |             <FD_SOCK/>
  |             <VERIFY_SUSPECT timeout="1500"/>
  |             <pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800" />
  |             <UNICAST timeout="600,1200,2400,4800" />
  |             <pbcast.STABLE desired_avg_gossip="400000"/>
  |             <FC max_credits="2000000" min_threshold="0.10"/>
  |             <FRAG2 frag_size="8192"/>
  |             <pbcast.GMS join_timeout="5000" shun="true" print_local_addr="true"/>
  |             <pbcast.STATE_TRANSFER/>
  |          </config>
  |       </attribute>
  |       
  |       <attribute name="StateRetrievalTimeout">20000</attribute>
  |       <attribute name="SyncReplTimeout">20000</attribute>
  | 
  |       <!-- Max number of milliseconds to wait for a lock acquisition -->
  |       <attribute name="LockAcquisitionTimeout">15000</attribute>
  | 
  |       <!-- Shutdown hook behavior.  Valid choices are: DEFAULT, REGISTER and DONT_REGISTER.
  |            If this element is omitted, DEFAULT is used.  -->
  |       <attribute name="ShutdownHookBehavior">DEFAULT</attribute>
  | 
  |       <!-- Enables or disables lazy unmarshalling.  If omitted, the default is that lazy unmarshalling is enabled. -->
  |       <attribute name="UseLazyDeserialization">true</attribute>      
  | 
  |       <!-- Specific eviction policy configurations. This is LRU -->
  |       <attribute name="EvictionPolicyConfig">
  |          <config>
  |             <attribute name="wakeUpIntervalSeconds">60</attribute>
  |             <!-- This defaults to 200000 if not specified -->
  |             <attribute name="eventQueueSize">200000</attribute>
  |          
  |             <attribute name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
  | 		
  | 			 
  |             <!-- Cache wide default -->
  |             <region name="/">
  |                <attribute name="maxNodes">5</attribute>
  |                <attribute name="maxAgeSeconds">6000</attribute>
  |                <attribute name="timeToLiveSeconds">6000</attribute>
  |             </region>
  |             <region name="/vendorcache">
  |                <attribute name="maxNodes">5</attribute>
  |                <attribute name="maxAgeSeconds">60</attribute>
  |                <attribute name="timeToLiveSeconds">60</attribute>
  |                <attribute name="maxAgeRemove">true</attribute>
  |             </region>
  |          </config>
  |       </attribute>
  |       
  |       <attribute name="CacheLoaderConfig">
  |          <config>
  |             <!-- if passivation is true, only the first cache loader is used; the rest are ignored -->
  |             <passivation>false</passivation>
  |             <preload>/vendorcache</preload>
  |             <shared>true</shared>
  |            
  |             <cacheloader>
  |                <class>org.jboss.cache.loader.JDBCCacheLoader</class>
  |     
  |                <properties>
  |                   cache.jdbc.table.name=jbosscachenew
  |                   cache.jdbc.table.create=true
  |                   cache.jdbc.table.drop=false
  |                   cache.jdbc.table.select=true
  |                   cache.jdbc.table.primarykey=jbosscachenew_pk
  |                   cache.jdbc.fqn.column=fqn
  |                   cache.jdbc.fqn.type=varchar(255)
  |                   cache.jdbc.node.column=node
  |                   cache.jdbc.node.type=blob
  |                   cache.jdbc.parent.column=parent
  |                   cache.jdbc.driver=com.mysql.jdbc.Driver
  |                   cache.jdbc.url=jdbc:mysql://server:3315/GIS_DEV
  |                   cache.jdbc.user=gis
  |                   cache.jdbc.password=tester
  |                   cache.jdbc.sql-concat=concat(1,2)
  |                </properties>
  |                
  |                <async>false</async>
  |                <fetchPersistentState>true</fetchPersistentState>
  | 
  |                <ignoreModifications>false</ignoreModifications>
  | 
  |                <purgeOnStartup>false</purgeOnStartup>
  |             </cacheloader>
  |             
  |          </config>
  |       </attribute>
  |       
  |    </mbean>
  | </server>
  | 

The modified LRUPolicy works fine and removes the data when the maxAge  of the nodes are reached. Can we have this feature in 3.0 please, if any coding/testing help is needed I can provide it. The fundamental reason to have this feature is as the Cache creates the data it should provide a way to clean it too, otherwise the Cache is not proving a full solution.



View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4167440#4167440

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4167440



More information about the jboss-user mailing list