asmuts 2004/04/27 14:08:25
Modified: src/java/org/apache/jcs/auxiliary/lateral/socket/tcp
LateralTCPSender.java
src/java/org/apache/jcs/auxiliary/lateral
LateralCacheNoWaitFacade.java
LateralCacheNoWait.java LateralCache.java
Log:
I saw the potential for a reported bug--where a get returns the wrong item under
heavy load from a lateral request. Although I do not recommend using laterals to get,
it should work.
I put the operations that must occur in order in a synchronized block, insuring that
gets from one lateral to another will not get mixed. Needs to be improved, but should
prevent any wrong elements from being returned. . . .
Get timeout failures now zombie the lateral and start recovery. Otherwise, since
they do not occur in the background, the cache could grind to a halt.
The worst case now is that if another lateral gets hung, a caller trying to get will
block until the timout. Removes and puts are all synchronous calls.
Revision Changes Path
1.9 +23 -5
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java
Index: LateralTCPSender.java
===================================================================
RCS file:
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- LateralTCPSender.java 15 Apr 2004 19:22:56 -0000 1.8
+++ LateralTCPSender.java 27 Apr 2004 21:08:24 -0000 1.9
@@ -75,6 +75,8 @@
/** Only block for 5 seconds before timing out on startup. */
private final static int openTimeOut = 5000;
+ /** Use to synchronize multiple threads that may be trying to get.*/
+ private Object getLock = new int[0];
/**
* Constructor for the LateralTCPSender object
@@ -212,8 +214,10 @@
/**
* Sends commands to the lateral cache listener and gets a response. I'm
* afraid that we could get into a pretty bad blocking situation here. This
- * needs work. I just wanted to get some form of get working. Will need some
- * sort of timeout.
+ * needs work. I just wanted to get some form of get working. However, get
+ * is not recommended for performance reasons. If you have 10 laterals, then
+ * you have to make 10 failed gets to find out none of the caches have the
+ * item.
*/
public ICacheElement sendAndReceive( LateralElementDescriptor led )
throws IOException
@@ -232,6 +236,15 @@
if ( oos != null )
{
+
+ // Synchronized to insure that the get requests to server from this
+ // sender and the responses are processed in order, else you could
+ // return the wrong item from the cache.
+ // This is a big block of code. May need to rethink this strategy.
+ // This may not be necessary.
+ // Normal puts, etc to laterals do not have to be synchronized.
+ synchronized ( this.getLock )
+ {
try
{
@@ -246,6 +259,7 @@
catch ( IOException ioe )
{
log.error( "Problem cleaning socket before send " + socket, ioe );
+ throw ioe;
}
// write object to listener
@@ -260,13 +274,14 @@
if ( ice == null )
{
//p( "ice is null" );
- // TODO: coutn misses
+ // TODO: count misses
}
}
catch ( IOException ioe )
{
log.error( "Could not open ObjectInputStream to " + socket, ioe
);
+ throw ioe;
}
catch ( Exception e )
{
@@ -288,8 +303,11 @@
log.error( "Detected problem with connection: " + e );
throw e;
}
- }
+ }
+ } // end synchronized block
+
return ice;
+
}// end sendAndReceive
// Service Methods //
1.8 +1 -1
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java
Index: LateralCacheNoWaitFacade.java
===================================================================
RCS file:
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- LateralCacheNoWaitFacade.java 15 Apr 2004 19:22:48 -0000 1.7
+++ LateralCacheNoWaitFacade.java 27 Apr 2004 21:08:24 -0000 1.8
@@ -91,7 +91,7 @@
if ( obj != null )
{
- // return after first success
+ // TODO: return after first success
// could do this simultaneously
// serious blocking risk here
return ( ICacheElement ) obj;
1.7 +189 -184
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWait.java
Index: LateralCacheNoWait.java
===================================================================
RCS file:
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWait.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- LateralCacheNoWait.java 15 Apr 2004 19:22:48 -0000 1.6
+++ LateralCacheNoWait.java 27 Apr 2004 21:08:24 -0000 1.7
@@ -1,6 +1,5 @@
package org.apache.jcs.auxiliary.lateral;
-
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
@@ -17,7 +16,6 @@
* limitations under the License.
*/
-
import java.io.IOException;
import java.io.Serializable;
import java.rmi.UnmarshalException;
@@ -40,195 +38,202 @@
* be processed in their order of arrival via the cache event queue processor.
*
*/
-public class LateralCacheNoWait implements AuxiliaryCache
+public class LateralCacheNoWait
+ implements AuxiliaryCache
{
- private final static Log log =
- LogFactory.getLog( LateralCacheNoWait.class );
-
- private final LateralCache cache;
- private ICacheEventQueue q;
+ private final static Log log =
+ LogFactory.getLog( LateralCacheNoWait.class );
- /**
- * Constructs with the given lateral cache, and fires up an event queue for
- * aysnchronous processing.
- *
- * @param cache
- */
- public LateralCacheNoWait( LateralCache cache )
- {
- this.cache = cache;
- this.q = new CacheEventQueue( new CacheAdaptor( cache ),
LateralCacheInfo.listenerId, cache.getCacheName() );
-
- // need each no wait to handle each of its real updates and removes, since
there may
- // be more than one per cache? alternativve is to have the cache
- // perform updates using a different method that spcifies the listener
- //this.q = new CacheEventQueue(new CacheAdaptor(this),
LateralCacheInfo.listenerId, cache.getCacheName());
- if ( cache.getStatus() == CacheConstants.STATUS_ERROR )
- {
- q.destroy();
- }
- }
+ private final LateralCache cache;
+ private ICacheEventQueue q;
- /** Description of the Method */
- public void update( ICacheElement ce )
- throws IOException
- {
+ /**
+ * Constructs with the given lateral cache, and fires up an event queue for
+ * aysnchronous processing.
+ *
+ * @param cache
+ */
+ public LateralCacheNoWait( LateralCache cache )
+ {
+ this.cache = cache;
+ this.q = new CacheEventQueue( new CacheAdaptor( cache ),
+ LateralCacheInfo.listenerId,
+ cache.getCacheName() );
+
+ // need each no wait to handle each of its real updates and removes, since
there may
+ // be more than one per cache? alternativve is to have the cache
+ // perform updates using a different method that spcifies the listener
+ //this.q = new CacheEventQueue(new CacheAdaptor(this),
LateralCacheInfo.listenerId, cache.getCacheName());
+ if ( cache.getStatus() == CacheConstants.STATUS_ERROR )
+ {
+ q.destroy();
+ }
+ }
+
+ /** Description of the Method */
+ public void update( ICacheElement ce ) throws IOException
+ {
+ try
+ {
+ q.addPutEvent( ce );
+ }
+ catch ( IOException ex )
+ {
+ log.error( ex );
+ q.destroy();
+ }
+ }
+
+ /** Synchronously reads from the lateral cache. */
+ public ICacheElement get( Serializable key )
+ {
+
+ if ( this.getStatus() != CacheConstants.STATUS_ERROR )
+ {
+ try
+ {
+ return cache.get( key );
+ }
+ catch ( UnmarshalException ue )
+ {
+ log.debug( "Retrying the get owing to UnmarshalException..." );
try
{
- q.addPutEvent( ce );
+ return cache.get( key );
}
catch ( IOException ex )
{
- log.error( ex );
- q.destroy();
- }
- }
-
- /** Synchronously reads from the lateral cache. */
- public ICacheElement get( Serializable key )
- {
- try
- {
- return cache.get( key );
- }
- catch ( UnmarshalException ue )
- {
- log.debug( "Retrying the get owing to UnmarshalException..." );
- try
- {
- return cache.get( key );
- }
- catch ( IOException ex )
- {
- log.error( "Failed in retrying the get for the second time." );
- q.destroy();
- }
- }
- catch ( IOException ex )
- {
- q.destroy();
- }
- return null;
- }
-
- public Set getGroupKeys(String groupName)
- {
- return cache.getGroupKeys(groupName);
- }
-
-
- /** Adds a remove request to the lateral cache. */
- public boolean remove( Serializable key )
- {
- try
- {
- q.addRemoveEvent( key );
- }
- catch ( IOException ex )
- {
- log.error( ex );
- q.destroy();
- }
- return false;
- }
-
- /** Adds a removeAll request to the lateral cache. */
- public void removeAll()
- {
- try
- {
- q.addRemoveAllEvent();
+ log.error( "Failed in retrying the get for the second time." );
+ q.destroy();
}
- catch ( IOException ex )
- {
- log.error( ex );
- q.destroy();
- }
- }
-
- /** Adds a dispose request to the lateral cache. */
- public void dispose()
- {
- try
- {
- q.addDisposeEvent();
- }
- catch ( IOException ex )
- {
- log.error( ex );
- q.destroy();
- }
- }
-
- /**
- * No lateral invokation.
- *
- * @return The size value
- */
- public int getSize()
- {
- return cache.getSize();
- }
-
- /**
- * No lateral invokation.
- *
- * @return The cacheType value
- */
- public int getCacheType()
- {
- return cache.getCacheType();
- }
-
- /**
- * Returns the asyn cache status. An error status indicates either the
- * lateral connection is not available, or the asyn queue has been
- * unexpectedly destroyed. No lateral invokation.
- *
- * @return The status value
- */
- public int getStatus()
- {
- return q.isAlive() ? cache.getStatus() : CacheConstants.STATUS_ERROR;
- }
-
- /**
- * Gets the cacheName attribute of the LateralCacheNoWait object
- *
- * @return The cacheName value
- */
- public String getCacheName()
- {
- return cache.getCacheName();
- }
-
- /**
- * Replaces the lateral cache service handle with the given handle and reset
- * the event queue by starting up a new instance.
- */
- public void fixCache( ILateralCacheService lateral )
- {
- cache.fixCache( lateral );
- resetEventQ();
- return;
- }
-
- /**
- * Resets the event q by first destroying the existing one and starting up
- * new one.
- */
- public void resetEventQ()
- {
- if ( q.isAlive() )
- {
- q.destroy();
- }
- this.q = new CacheEventQueue( new CacheAdaptor( cache ),
LateralCacheInfo.listenerId, cache.getCacheName() );
- }
-
- /** Description of the Method */
- public String toString()
- {
- return "LateralCacheNoWait: " + cache.toString();
- }
+ }
+ catch ( IOException ex )
+ {
+ q.destroy();
+ }
+ }
+ return null;
+ }
+
+ public Set getGroupKeys( String groupName )
+ {
+ return cache.getGroupKeys( groupName );
+ }
+
+ /** Adds a remove request to the lateral cache. */
+ public boolean remove( Serializable key )
+ {
+ try
+ {
+ q.addRemoveEvent( key );
+ }
+ catch ( IOException ex )
+ {
+ log.error( ex );
+ q.destroy();
+ }
+ return false;
+ }
+
+ /** Adds a removeAll request to the lateral cache. */
+ public void removeAll()
+ {
+ try
+ {
+ q.addRemoveAllEvent();
+ }
+ catch ( IOException ex )
+ {
+ log.error( ex );
+ q.destroy();
+ }
+ }
+
+ /** Adds a dispose request to the lateral cache. */
+ public void dispose()
+ {
+ try
+ {
+ q.addDisposeEvent();
+ }
+ catch ( IOException ex )
+ {
+ log.error( ex );
+ q.destroy();
+ }
+ }
+
+ /**
+ * No lateral invokation.
+ *
+ * @return The size value
+ */
+ public int getSize()
+ {
+ return cache.getSize();
+ }
+
+ /**
+ * No lateral invokation.
+ *
+ * @return The cacheType value
+ */
+ public int getCacheType()
+ {
+ return cache.getCacheType();
+ }
+
+ /**
+ * Returns the asyn cache status. An error status indicates either the
+ * lateral connection is not available, or the asyn queue has been
+ * unexpectedly destroyed. No lateral invokation.
+ *
+ * @return The status value
+ */
+ public int getStatus()
+ {
+ return q.isAlive() ? cache.getStatus() : CacheConstants.STATUS_ERROR;
+ }
+
+ /**
+ * Gets the cacheName attribute of the LateralCacheNoWait object
+ *
+ * @return The cacheName value
+ */
+ public String getCacheName()
+ {
+ return cache.getCacheName();
+ }
+
+ /**
+ * Replaces the lateral cache service handle with the given handle and reset
+ * the event queue by starting up a new instance.
+ */
+ public void fixCache( ILateralCacheService lateral )
+ {
+ cache.fixCache( lateral );
+ resetEventQ();
+ return;
+ }
+
+ /**
+ * Resets the event q by first destroying the existing one and starting up
+ * new one.
+ */
+ public void resetEventQ()
+ {
+ if ( q.isAlive() )
+ {
+ q.destroy();
+ }
+ this.q = new CacheEventQueue( new CacheAdaptor( cache ),
+ LateralCacheInfo.listenerId,
+ cache.getCacheName() );
+ }
+
+ /** Description of the Method */
+ public String toString()
+ {
+ return "LateralCacheNoWait: " + cache.toString();
+ }
}
1.8 +1 -1
jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCache.java
Index: LateralCache.java
===================================================================
RCS file:
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/auxiliary/lateral/LateralCache.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- LateralCache.java 15 Apr 2004 19:22:48 -0000 1.7
+++ LateralCache.java 27 Apr 2004 21:08:24 -0000 1.8
@@ -142,7 +142,7 @@
catch ( Exception e )
{
log.error( e );
- // do something with this
+ handleException( e, "Failed to get " + key + " from " +
cattr.getCacheName() );
}
}
return obj;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]