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(a)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(a)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#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...