Regions were not the problem though, all the items were in one region, the problem seemed to be that after restarting some of the machines sometimes you would get a result like this.
get("D") returns "valueD"
get("A") returns "valueA"
get("B") returns "valueB"
get("A") returns "valueA"
get("C") returns "valueC"
get("D") returns "valueC" <-- incorrect this was the value for the last get!
From this point on, getting key "D" continues to return "ValueC" but should have "ValueD".
This occurs after restarting a cache on one machine (possibly a machine doing lot's of puts). I think not ALL items got out of sync but once an item had gone wrong a get on the keys that had gone wrong continued to return the wrong value.
Matt.
Aaron Smuts wrote:
This is the method in the TCP listener that updates the cache. The cache element is what is deserialized. It would be a miracle if it could get corrupted and still work. If there is a problem it would be in the creation of the CacheElement.
public void handlePut( ICacheElement element ) throws IOException { if ( log.isDebugEnabled() ) { log.debug( "handlePut> cacheName=" + element.getCacheName() + ", key=" + element.getKey() ); }
getCache( element.getCacheName() ).localUpdate( element ); }
The CacheElement method is here:
public String getCacheName() { return this.cacheName; }
The put method of the CacheAccess class creates the CacheElement wrapper:
public void put( Object key, Object val, IElementAttributes attr ) throws CacheException { if ( key == null ) { throw new CacheException( "Key must not be null" ); } else if ( val == null ) { throw new CacheException( "Value must not be null" ); }
// Create the element and update. This may throw an IOException which // should be wrapped by cache access.
try { CacheElement ce = new CacheElement( cacheControl.getCacheName(), (Serializable) key, (Serializable) val );
ce.setElementAttributes( attr );
cacheControl.update( ce ); } catch ( Exception e ) { throw new CacheException( e ); } }
The cacheControl varialbe references the CacheManager. The method getCacheName() is returning an instance variable. This should be fine, but it would be better to get it from the cache configuration.
This variable is set in the CacheManager constructor.
When you retrieve a cache from the cache manager directly, this is called:
/** Gets the cache attribute of the CacheHub object */ public CompositeCache getCache( String cacheName ) { return getCache( cacheName, this.defaultCacheAttr.copy() ); }
/** Gets the cache attribute of the CacheHub object */ public CompositeCache getCache( String cacheName, ICompositeCacheAttributes cattr ) { cattr.setCacheName( cacheName ); return getCache( cattr, this.defaultElementAttr ); }
/** Gets the cache attribute of the CacheHub object */ public CompositeCache getCache( String cacheName, ICompositeCacheAttributes cattr, IElementAttributes attr ) { cattr.setCacheName( cacheName ); return getCache( cattr, this.defaultElementAttr ); }
/** Gets the cache attribute of the CacheHub object */ public CompositeCache getCache( ICompositeCacheAttributes cattr ) { return getCache( cattr, this.defaultElementAttr ); }
/** * If the cache is created the CacheAttributes and the element Attributes * will be ignored. Currently there is no overiding once it is set up. * Overriding hte default elemental atributes will require cahnging the way * the atributes are assigned to elements. Get cache creates a cache with * defaults if none are specified. We might want to create separate method * for creating/getting. . . */ public CompositeCache getCache( ICompositeCacheAttributes cattr, IElementAttributes attr ) { CompositeCache cache;
synchronized ( caches ) { cache = ( CompositeCache ) caches.get( cattr.getCacheName() ); if ( cache == null ) { cattr.setCacheName( cattr.getCacheName() );
CompositeCacheConfigurator configurator = new CompositeCacheConfigurator( this );
cache = configurator.parseRegion( this.props, cattr.getCacheName(), this.defaultAuxValues, cattr );
caches.put( cattr.getCacheName(), cache ); } }
return cache; }
There is no clear way that the name could be set incorrectly, unless you called one of the later methods without setting the cacheName.
The access classes and the JCS class all access retrieve cashes with the region name, which gets set as the cachename.
public static JCS getInstance( String region ) throws CacheException { ensureCacheManager();
return new JCS( ( CompositeCache ) cacheMgr.getCache( region ) ); }
/** * Get a JCS which accesses the provided region. * * @param region Region that return JCS will provide access to * @param icca CacheAttributes for region * @return A JCS which provides access to a given region. * @exception CacheException */ public static JCS getInstance( String region, ICompositeCacheAttributes icca ) throws CacheException { ensureCacheManager();
return new JCS( ( CompositeCache ) cacheMgr.getCache( region, icca ) ); }
I can't see where a region switch could happen unless the region was created by calling the cachemanager directly and not passing the cachename. I'm still hunting.
In the configurator this is called:
auxAttr = auxAttr.copy();
log.debug( "Parsing options for '" + attrName + "'" ); PropertySetter.setProperties( auxAttr, props, attrName + "." ); auxAttr.setCacheName( regName );
log.debug( "End of parsing for '" + attrName + "'" );
// GET CACHE FROM FACTORY WITH ATTRIBUTES auxAttr.setCacheName( regName ); auxCache = auxFac.createCache( auxAttr, cache ); return auxCache;
In the LateralCacheFactory this is called:
public AuxiliaryCache createCache( AuxiliaryCacheAttributes iaca, CompositeCache cache ) { LateralCacheAttributes lac = ( LateralCacheAttributes ) iaca; ArrayList noWaits = new ArrayList();
if ( lac.getTransmissionType() == lac.UDP ) { LateralCacheManager lcm = LateralCacheManager.getInstance( lac ); ICache ic = lcm.getCache( lac.getCacheName() ); if ( ic != null ) { noWaits.add( ic ); } } else if ( lac.getTransmissionType() == lac.JAVAGROUPS ) { LateralCacheManager lcm = LateralCacheManager.getInstance( lac ); ICache ic = lcm.getCache( lac.getCacheName() ); if ( ic != null ) { noWaits.add( ic ); } } else if ( lac.getTransmissionType() == lac.TCP ) {
//pars up the tcp servers and set the tcpServer value and // get the manager and then get the cache //Iterator it = lac.tcpServers.iterator(); //while( it.hasNext() ) {
StringTokenizer it = new StringTokenizer( lac.tcpServers, "," ); while ( it.hasMoreElements() ) { //String server = (String)it.next(); String server = ( String ) it.nextElement(); if ( log.isDebugEnabled() ) { log.debug( "tcp server = " + server ); } lac.setTcpServer( server ); LateralCacheManager lcm = LateralCacheManager.getInstance( lac ); ICache ic = lcm.getCache( lac.getCacheName() ); if ( ic != null ) { noWaits.add( ic ); } else { //p( "noWait is null" ); } }
} else if ( lac.getTransmissionType() == lac.XMLRPC ) {
//pars up the tcp servers and set the tcpServer value and // get the manager and then get the cache //Iterator it = lac.tcpServers.iterator(); //while( it.hasNext() ) {
StringTokenizer it = new StringTokenizer( lac.getHttpServers(), "," ); while ( it.hasMoreElements() ) { //String server = (String)it.next(); String server = ( String ) it.nextElement(); //p( "tcp server = " + server ); lac.setHttpServer( server ); LateralCacheManager lcm = LateralCacheManager.getInstance( lac ); ICache ic = lcm.getCache( lac.getCacheName() ); if ( ic != null ) { noWaits.add( ic ); } else { log.warn( "noWait is null" ); } }
} else if ( lac.getTransmissionType() == lac.HTTP ) { StringTokenizer it = new StringTokenizer( lac.getHttpServers(), "," ); while ( it.hasMoreElements() ) { String server = ( String ) it.nextElement(); lac.setHttpServer( server ); LateralCacheManager lcm = LateralCacheManager.getInstance( lac ); ICache ic = lcm.getCache( lac.getCacheName() ); if ( ic != null ) { noWaits.add( ic ); } } }
LateralCacheNoWaitFacade lcnwf = new LateralCacheNoWaitFacade( ( LateralCacheNoWait[] ) noWaits.toArray( new LateralCacheNoWait[ 0 ] ), iaca.getCacheName() );
return lcnwf; } // end createCache
This is the method in the LateralCacheManager:
public AuxiliaryCache getCache( String cacheName ) { LateralCacheNoWait c = null; synchronized ( caches ) { //c = (LateralCache)caches.get(cacheName); c = ( LateralCacheNoWait ) caches.get( cacheName ); if ( c == null ) { c = new LateralCacheNoWait( new LateralCache( lca, lateralService ) ); caches.put( cacheName, c ); } }
try { if ( lca.getTransmissionType() == lca.TCP ) { addLateralCacheListener( cacheName, LateralTCPListener.getInstance( lca ) ); } } catch ( IOException ioe ) { log.error( ioe ); } catch ( Exception e ) { log.error( e ); }
// TODO: need listener repair
// if ( log.isDebugEnabled() ) // { // log.debug("LateralManager stats : " + getStats()); // }
return c; }
Here's the LateralCache constructor:
protected LateralCache( ILateralCacheAttributes cattr, ILateralCacheService lateral ) { this.cacheName = cattr.getCacheName(); this.cattr = cattr; this.lateral = lateral; }
Nothing uses the cachename here.
I just can't see how this could be happening.
Aaron
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
