commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t.@apache.org
Subject svn commit: r1195252 - in /commons/proper/jcs/trunk/src: changes/changes.xml java/org/apache/jcs/admin/JCSAdminBean.java java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java
Date Sun, 30 Oct 2011 21:29:11 GMT
Author: tv
Date: Sun Oct 30 21:29:10 2011
New Revision: 1195252

URL: http://svn.apache.org/viewvc?rev=1195252&view=rev
Log:
Made RemoteCacheServer public, added remote cache remove feature to JCSAdminBean. Fixes JCS-68

Modified:
    commons/proper/jcs/trunk/src/changes/changes.xml
    commons/proper/jcs/trunk/src/java/org/apache/jcs/admin/JCSAdminBean.java
    commons/proper/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java

Modified: commons/proper/jcs/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/src/changes/changes.xml?rev=1195252&r1=1195251&r2=1195252&view=diff
==============================================================================
--- commons/proper/jcs/trunk/src/changes/changes.xml (original)
+++ commons/proper/jcs/trunk/src/changes/changes.xml Sun Oct 30 21:29:10 2011
@@ -20,6 +20,10 @@
 	</properties>
 	<body>
 		<release version="2.0" date="unreleased" description="JDK 1.5 based major release">
+            <action dev="tv" type="fix" issue="JCS-68" due-to="Niall Gallagher">
+                Made RemoteCacheServer public, added remote cache remove feature to
+                JCSAdminBean
+            </action>
             <action dev="tv" type="fix" issue="JCS-82" due-to="Nikunj Trivedi">
                 Use oos.writeUnshared() for LateralTCPSender
             </action>

Modified: commons/proper/jcs/trunk/src/java/org/apache/jcs/admin/JCSAdminBean.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/src/java/org/apache/jcs/admin/JCSAdminBean.java?rev=1195252&r1=1195251&r2=1195252&view=diff
==============================================================================
--- commons/proper/jcs/trunk/src/java/org/apache/jcs/admin/JCSAdminBean.java (original)
+++ commons/proper/jcs/trunk/src/java/org/apache/jcs/admin/JCSAdminBean.java Sun Oct 30 21:29:10
2011
@@ -29,8 +29,9 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.remote.server.RemoteCacheServer;
+import org.apache.jcs.auxiliary.remote.server.RemoteCacheServerFactory;
+import org.apache.jcs.engine.CacheElementSerialized;
 import org.apache.jcs.engine.behavior.ICacheElement;
 import org.apache.jcs.engine.behavior.IElementAttributes;
 import org.apache.jcs.engine.control.CompositeCache;
@@ -46,9 +47,6 @@ import org.apache.jcs.engine.memory.util
  */
 public class JCSAdminBean
 {
-    /** The logger. */
-    private static final Log log = LogFactory.getLog( JCSAdminBean.class );
-
     /** The cache manager. */
     private final CompositeCacheManager cacheHub = CompositeCacheManager.getInstance();
 
@@ -146,80 +144,225 @@ public class JCSAdminBean
     }
 
     /**
-     * Tries to estimate how much data is in a region. This is expensive. If there are any
non
-     * serializable objects in the region, the count will stop when it encounters the first
one.
-     * <p>
-     * @param cache
-     * @return int
-     * @throws Exception
+     * Tries to estimate how much data is in a region. This is expensive. If there are any
non serializable objects in
+     * the region or an error occurs, suppresses exceptions and returns 0.
+     * <p/>
+     *
+     * @return int The size of the region in bytes.
      */
-    public int getByteCount( CompositeCache cache )
-        throws Exception
+    public int getByteCount(CompositeCache cache) throws Exception
     {
-        IMemoryCache memCache = cache.getMemoryCache();
-
-        Iterator<Map.Entry<Serializable, MemoryElementDescriptor>> iter = memCache.getIterator();
-
-        CountingOnlyOutputStream counter = new CountingOnlyOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream( counter );
+        if (cache == null)
+        {
+            throw new IllegalArgumentException("The cache object specified was null.");
+        }
 
-        // non serializable objects will cause problems here
-        // stop at the first non serializable exception.
+        long size = 0;
         try
         {
-            while ( iter.hasNext() )
+            IMemoryCache memCache = cache.getMemoryCache();
+
+            Iterator<Map.Entry<Serializable, MemoryElementDescriptor>> iter =
memCache.getIterator();
+            while (iter.hasNext())
             {
                 MemoryElementDescriptor me = iter.next().getValue();
-                out.writeObject( me.ce.getVal() );
+                ICacheElement ice = me.ce;
+
+                if (ice instanceof CacheElementSerialized)
+                {
+                    size = size + ((CacheElementSerialized) ice).getSerializedValue().length;
+                }
+                else
+                {
+                    Serializable element = ice.getVal();
+
+                    //CountingOnlyOutputStream: Keeps track of the number of bytes written
to it, but doesn't write them anywhere.
+                    CountingOnlyOutputStream counter = new CountingOnlyOutputStream();
+                    try
+                    {
+                        ObjectOutputStream out = new ObjectOutputStream(counter);
+                        out.writeObject(element);
+                    }
+                    catch (IOException e)
+                    {
+                        throw new RuntimeException("IOException while trying to measure the
size of the cached element", e);
+                    }
+
+                    // 4 bytes lost for the serialization header
+                    size = size + counter.getCount() - 4;
+                }
+            }
+
+            if (size > Integer.MAX_VALUE)
+            {
+                throw new IllegalStateException("The size of cache " + cache.getCacheName()
+ " (" + size + " bytes) is too large to be represented as an integer.");
             }
         }
-        catch ( Exception e )
+        catch (Exception e)
         {
-            log.info( "Problem getting byte count.  Likely cause is a non serializable object."
+ e.getMessage() );
+            // throw new RuntimeException("Failed to calculate the size of cache region ["
+ cache.getCacheName() + "]:" + e, e);
+            return 0;
         }
 
-        // 4 bytes lost for the serialization header
-        return counter.getCount() - 4;
+        return (int) size;
     }
 
     /**
      * Clears all regions in the cache.
-     * <p>
-     * @throws IOException
+     * <p/>
+     * If this class is running within a remote cache server, clears all regions via the
<code>RemoteCacheServer</code>
+     * API, so that removes will be broadcast to client machines. Otherwise clears all regions
in the cache directly via
+     * the usual cache API.
      */
-    public void clearAllRegions()
-        throws IOException
+    public void clearAllRegions() throws IOException
     {
-        String[] names = cacheHub.getCacheNames();
+        if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
+        {
+            // Not running in a remote cache server.
+            // Remove objects from the cache directly, as no need to broadcast removes to
client machines...
+
+            String[] names = cacheHub.getCacheNames();
 
-        for ( int i = 0; i < names.length; i++ )
+            for (int i = 0; i < names.length; i++)
+            {
+                cacheHub.getCache(names[i]).removeAll();
+            }
+        }
+        else
         {
-            cacheHub.getCache( names[i] ).removeAll();
+            // Running in a remote cache server.
+            // Remove objects via the RemoteCacheServer API, so that removes will be broadcast
to client machines...
+            try
+            {
+                String[] cacheNames = CompositeCacheManager.getInstance().getCacheNames();
+
+                // Call remoteCacheServer.removeAll(String) for each cacheName...
+                RemoteCacheServer remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
+                for (int i = 0; i < cacheNames.length; i++)
+                {
+                    String cacheName = cacheNames[i];
+                    remoteCacheServer.removeAll(cacheName);
+                }
+            }
+            catch (IOException e)
+            {
+                throw new IllegalStateException("Failed to remove all elements from all cache
regions: " + e, e);
+            }
         }
     }
 
     /**
      * Clears a particular cache region.
-     * <p>
-     * @param cacheName
-     * @throws IOException
+     * <p/>
+     * If this class is running within a remote cache server, clears the region via the <code>RemoteCacheServer</code>
+     * API, so that removes will be broadcast to client machines. Otherwise clears the region
directly via the usual
+     * cache API.
      */
-    public void clearRegion( String cacheName )
-        throws IOException
+    public void clearRegion(String cacheName) throws IOException
     {
-        cacheHub.getCache( cacheName ).removeAll();
+        if (cacheName == null)
+        {
+            throw new IllegalArgumentException("The cache name specified was null.");
+        }
+        if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
+        {
+            // Not running in a remote cache server.
+            // Remove objects from the cache directly, as no need to broadcast removes to
client machines...
+            cacheHub.getCache(cacheName).removeAll();
+        }
+        else
+        {
+            // Running in a remote cache server.
+            // Remove objects via the RemoteCacheServer API, so that removes will be broadcast
to client machines...
+            try
+            {
+                // Call remoteCacheServer.removeAll(String)...
+                RemoteCacheServer remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
+                remoteCacheServer.removeAll(cacheName);
+            }
+            catch (IOException e)
+            {
+                throw new IllegalStateException("Failed to remove all elements from cache
region [" + cacheName + "]: " + e, e);
+            }
+        }
     }
 
     /**
      * Removes a particular item from a particular region.
-     * <p>
+     * <p/>
+     * If this class is running within a remote cache server, removes the item via the <code>RemoteCacheServer</code>
+     * API, so that removes will be broadcast to client machines. Otherwise clears the region
directly via the usual
+     * cache API.
+     *
      * @param cacheName
      * @param key
+     *
      * @throws IOException
      */
-    public void removeItem( String cacheName, String key )
-        throws IOException
+    public void removeItem(String cacheName, String key) throws IOException
     {
-        cacheHub.getCache( cacheName ).remove( key );
+        if (cacheName == null)
+        {
+            throw new IllegalArgumentException("The cache name specified was null.");
+        }
+        if (key == null)
+        {
+            throw new IllegalArgumentException("The key specified was null.");
+        }
+        if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
+        {
+            // Not running in a remote cache server.
+            // Remove objects from the cache directly, as no need to broadcast removes to
client machines...
+            cacheHub.getCache(cacheName).remove(key);
+        }
+        else
+        {
+            // Running in a remote cache server.
+            // Remove objects via the RemoteCacheServer API, so that removes will be broadcast
to client machines...
+            try
+            {
+                Object keyToRemove = null;
+                CompositeCache cache = CompositeCacheManager.getInstance().getCache(cacheName);
+
+                // A String key was supplied, but to remove elements via the RemoteCacheServer
API, we need the
+                // actual key object as stored in the cache (i.e. a Serializable object).
To find the key in this form,
+                // we iterate through all keys stored in the memory cache until we find one
whose toString matches
+                // the string supplied...
+                Object[] allKeysInCache = cache.getMemoryCache().getKeyArray();
+                for (int i = 0; i < allKeysInCache.length; i++)
+                {
+                    Object keyInCache = allKeysInCache[i];
+                    if (keyInCache.toString().equals(key))
+                    {
+                        if (keyToRemove == null)
+                        {
+                            keyToRemove = keyInCache;
+                        }
+                        else
+                        {
+                            // A key matching the one specified was already found...
+                            throw new IllegalStateException("Unexpectedly found duplicate
keys in the cache region matching the key specified.");
+                        }
+                    }
+                }
+                if (keyToRemove == null)
+                {
+                    throw new IllegalStateException("No match for this key could be found
in the set of keys retrieved from the memory cache.");
+                }
+                if (!(keyToRemove instanceof Serializable))
+                {
+                    throw new IllegalStateException("Found key [" + keyToRemove + ", " +
keyToRemove.getClass() + "] in cache matching key specified, however key found in cache is
unexpectedly not serializable.");
+                }
+                // At this point, we have retrieved the matching Serializable key.
+
+                // Call remoteCacheServer.remove(String, Serializable)...
+                RemoteCacheServer remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
+                remoteCacheServer.remove(cacheName, key);
+            }
+            catch (Exception e)
+            {
+                throw new IllegalStateException("Failed to remove element with key [" + key
+ ", " + key.getClass() + "] from cache region [" + cacheName + "]: " + e, e);
+            }
+        }
     }
 }

Modified: commons/proper/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java?rev=1195252&r1=1195251&r2=1195252&view=diff
==============================================================================
--- commons/proper/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java
(original)
+++ commons/proper/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java
Sun Oct 30 21:29:10 2011
@@ -62,7 +62,7 @@ import org.apache.jcs.engine.logging.beh
  * between the two servers. Since caches are usually high get and low put, this should allow
you to
  * scale.
  */
-class RemoteCacheServer
+public class RemoteCacheServer
     extends UnicastRemoteObject
     implements IRemoteCacheService, IRemoteCacheObserver, IRemoteCacheServiceAdmin, Unreferenced
 {
@@ -117,7 +117,7 @@ class RemoteCacheServer
      * @param rcsa
      * @throws RemoteException
      */
-    RemoteCacheServer( IRemoteCacheServerAttributes rcsa )
+    protected RemoteCacheServer( IRemoteCacheServerAttributes rcsa )
         throws RemoteException
     {
         super( rcsa.getServicePort() );
@@ -133,7 +133,7 @@ class RemoteCacheServer
      * @param customRMISocketFactory
      * @throws RemoteException
      */
-    RemoteCacheServer( IRemoteCacheServerAttributes rcsa, RMISocketFactory customRMISocketFactory
)
+    protected RemoteCacheServer( IRemoteCacheServerAttributes rcsa, RMISocketFactory customRMISocketFactory
)
         throws RemoteException
     {
         super( rcsa.getServicePort(), customRMISocketFactory, customRMISocketFactory );



Mime
View raw message