JBoss Community

CacheLoader store not recreating keys/values

created by jaysmith in JBoss Cache - View the full discussion

Hi there,

 

I have a simple proof of concept JUnit that creates a cache, creates a node, creates a test object and adds this object to the node.  The cache is configured with a FileCacheLoader, passivation disabled and eviction happens after 2 seconds.

What I would expect to see is that when the object is added to the node, both RAM and disk are written to, after 2 seconds then memory should be cleared. After that time, a read should load the node and the object that the node contains back into memory.

However, what I'm actually seeing is different. After 2 seconds has elapsed and the node has been evicted from RAM, a read recreates the node from the persistent store but it is empty i.e. the object that the node orginally stored is no longer there.

 

My configuration:

<?xml version="1.0" encoding="UTF-8"?>

<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.2">


   <!--
      isolation levels supported: READ_COMMITTED and REPEATABLE_READ
      nodeLockingSchemes: mvcc, pessimistic (deprecated), optimistic (deprecated)
   -->
   <locking
         isolationLevel="REPEATABLE_READ"
         lockParentForChildInsertRemove="false"
         lockAcquisitionTimeout="20000"
         nodeLockingScheme="mvcc"
         writeSkewCheck="false"
         useLockStriping="true"
         concurrencyLevel="500"/>

   <!--
      Used to register a transaction manager and participate in ongoing transactions.
      -->
   <transaction
         transactionManagerLookupClass="org.jboss.cache.transaction.GenericTransactionManagerLookup"
         syncRollbackPhase="false"
         syncCommitPhase="false"/>

   <!--
      Used to register JMX statistics in any available MBean server
      -->
   <jmxStatistics enabled="false"/>

   <!--
      If region based marshalling is used, defines whether new regions are inactive on startup.
   -->
   <startup regionsInactiveOnStartup="true"/>

   <!--
      Used to register JVM shutdown hooks.
      hookBehavior: DEFAULT, REGISTER, DONT_REGISTER
   -->
   <shutdown hookBehavior="DEFAULT"/>

   <!--
      Used to define async listener notification thread pool size
   -->
   <listeners asyncPoolSize="1" asyncQueueSize="100000"/>

   <!--
      Used to enable invocation batching and allow the use of Cache.startBatch()/endBatch() methods.
   -->
   <invocationBatching enabled="false"/>

   <!--
      serialization related configuration, used for replication and cache loading
   -->
   <serialization objectInputStreamPoolSize="12" objectOutputStreamPoolSize="14" version="3.0.0"
         marshallerClass="org.jboss.cache.marshall.VersionAwareMarshaller" useLazyDeserialization="false"
         useRegionBasedMarshalling="false"/>

   <!--
      Eviction configuration.  WakeupInterval defines how often the eviction thread runs, in milliseconds.  0 means
      the eviction thread will never run.
   -->
   <eviction wakeUpInterval="500">
      <default algorithmClass="org.jboss.cache.eviction.LRUAlgorithm" eventQueueSize="200000">
         <property name="maxNodes" value="5000" />
         <property name="timeToLive" value="1000" />
      </default>
      <region name="/griffin_peter">
         <property name="timeToLive" value="2000" />
         <!--<property name="maxAge" value="10000" />-->
      </region>
      <region name="/org/jboss/data2" algorithmClass="org.jboss.cache.eviction.FIFOAlgorithm" eventQueueSize="100000">
         <property name="maxNodes" value="3000" />
         <property name="minTimeToLive" value="4000" />
      </region>
   </eviction>

   <!--
      Cache loaders.

      If passivation is enabled, state is offloaded to the cache loaders ONLY when evicted.  Similarly, when the state
      is accessed again, it is removed from the cache loader and loaded into memory.

      Otherwise, state is always maintained in the cache loader as well as in memory.

      Set 'shared' to true if all instances in the cluster use the same cache loader instance, e.g., are talking to the
      same database.
   -->
   <loaders passivation="false" shared="false">
      <preload>
         <node fqn="/griffin_peter"/>
      </preload>

      <loader class="org.jboss.cache.loader.FileCacheLoader" async="true" fetchPersistentState="true"
              ignoreModifications="false" purgeOnStartup="true">
         <properties>
            check.character.portability=false
            location=/web/dev/jboss-cache
         </properties>
         <singletonStore enabled="false" class="org.jboss.cache.loader.SingletonStoreCacheLoader">
            <properties>
               pushStateWhenCoordinator=true
               pushStateWhenCoordinatorTimeout=20000
            </properties>
         </singletonStore>
      </loader>
   </loaders>
</jbosscache>

 

Here is the code I have (based on code in JBoss Cache User Guide 3.x.x)

 

package tests.cache.loader;

 

import org.jboss.cache.Cache;
import org.jboss.cache.CacheFactory;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

 

public class CustomCacheLoaderTest {
    /** cache. */
    private static Cache<String, Object> cache = null;

    class TestTO {
        private String field1;
        public String toString() {
            return this.getClass().getSimpleName() + ": field1=" + field1;
        }
    }

    @AfterClass
    public final static void afterClass() throws Exception {
        cache.stop();
        cache.destroy();
        cache = null;
    }

    @BeforeClass
    public final static void beforeClass() throws Exception {
        CacheFactory cacheFactory = new DefaultCacheFactory();
        cache = cacheFactory.createCache("jboss-cache-configuration.xml");
        cache.create();
        cache.start();
    }

    @Test
    public final void put() throws Exception {
        Object listener = new CustomCacheListener();
        cache.addCacheListener(listener);
        Node rootNode = cache.getRoot();
        Fqn peterGriffinFqn = Fqn.fromString("/griffin_peter");
        Node peterGriffinNode = rootNode.addChild(peterGriffinFqn);

 

        TestTO testTO = new TestTO();
        testTO.field1 = "This is a test string!";
        peterGriffinNode.put("testTO", testTO);
        System.out.println("Fqn: /griffin_peter: Key=testTO; Value="
                + cache.get("/griffin_peter", "testTO"));

 

        System.out.println("\nWaiting for 4000 milliseconds ...");
        Thread.sleep(4000);
        java.util.Map data = cache.getData(Fqn.fromString("/griffin_peter"));
        System.out.println("data.size()=" + data.size());
        System.out.println("Fqn: /griffin_peter: Key=testTO; Value="
                + cache.get("/griffin_peter", "testTO"));
    }

}

 

this outputs:

Fqn: /griffin_peter: Key=testTO; Value=TestTO: field1=This is a test string!

 

Waiting for 4000 milliseconds ...

data.size()=0

Fqn: /griffin_peter: Key=testTO; Value=null



When I plug a Cache Listener in, the output is:

09:04:07.678 [CustomCacheListener] Created node: /griffin_peter

09:04:07.803 [CustomCacheListener] Created node: /griffin_peter

09:04:07.819 [CustomCacheListener] Visited node: /griffin_peter

09:04:07.819 [CustomCacheListener] Visited node: /griffin_peter

Fqn: /griffin_peter: Key=testTO; Value=TestTO: field1=This is a test string!

 

Waiting for 4000 milliseconds ...

09:04:09.866 [CustomCacheListener] Evicted node: /griffin_peter

09:04:09.866 [CustomCacheListener] Evicted node: /griffin_peter

09:04:11.819 [CustomCacheListener] Created node: /griffin_peter

09:04:11.819 [CustomCacheListener] Created node: /griffin_peter

data.size()=0

09:04:11.819 [CustomCacheListener] Visited node: /griffin_peter

09:04:11.819 [CustomCacheListener] Visited node: /griffin_peter

Fqn: /griffin_peter: Key=testTO; Value=null



So, the RAM is evicted at 09:04:09.866, node is recreated from backend store at 09:04:11.819 but the value for key testTO is null when it should be a TestTO object with field1 populated.



Any ideas why the backend store isn't storing keys and values?

Reply to this message by going to Community

Start a new discussion in JBoss Cache at Community