jakarta-jcs-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Aaron Smuts <asm...@yahoo.com>
Subject RE: [jira] Commented: (JCS-68) Admin.jsp on remote cache server does not broadcast removes - patch
Date Mon, 31 Aug 2009 17:58:03 GMT
I have no idea.  Strange.  

But to make a patch, you have to checkout the code.  . . . 

--- On Mon, 8/31/09, Tim Cronin <Tim.Cronin@autonomy.com> wrote:

> From: Tim Cronin <Tim.Cronin@autonomy.com>
> Subject: RE: [jira] Commented: (JCS-68) Admin.jsp on remote cache server does not broadcast
removes - patch
> To: "JCS Developers List" <jcs-dev@jakarta.apache.org>
> Date: Monday, August 31, 2009, 8:22 AM
> Any reason that the RemoteCacheServer
> class is not exposed in the
> Javadocs?
> 
> http://jakarta.apache.org/jcs/apidocs/org/apache/jcs/auxiliary/remote/se
> rver/RemoteCacheServerFactory.html
> 
> 
> -----Original Message-----
> From: Aaron Smuts (JIRA) [mailto:jira@apache.org] 
> Sent: Monday, August 31, 2009 8:29 AM
> To: jcs-dev@jakarta.apache.org
> Subject: [jira] Commented: (JCS-68) Admin.jsp on remote
> cache server
> does not broadcast removes - patch
> 
> 
>     [
> https://issues.apache.org/jira/browse/JCS-68?page=com.atlassian.jira.plu
> gin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12749487#act
> ion_12749487 ] 
> 
> Aaron Smuts commented on JCS-68:
> --------------------------------
> 
> Thanks, this is a good idea.  Why are you calling the
> remove method via
> reflection?  That's too fragile.  Especially
> without any unit tests.  I
> need unit tests for all changes.  
> 
> > Admin.jsp on remote cache server does not broadcast
> removes - patch
> >
> -------------------------------------------------------------------
> >
> >             
>    Key: JCS-68
> >             
>    URL: https://issues.apache.org/jira/browse/JCS-68
> >         
>    Project: JCS
> >          Issue Type: Bug
> >          Components: RMI
> Remote Cache
> >    Affects Versions: jcs-1.3, jcs-1.4-dev
> >         Environment:
> All
> >            Reporter:
> Niall Gallagher
> >            Assignee:
> Aaron Smuts
> >            Priority:
> Minor
> >   Original Estimate: 0.5h
> >  Remaining Estimate: 0.5h
> >
> > We'd like to contribute some patches to fix an issue
> with the
> JCSAdmin.jsp when it's used on a JCS remote cache server.
> > We use this JSP on our remote cache server. This
> allows us to browse
> the objects stored in our distributed cache (i.e. uploaded
> by the client
> servers), and allows us to remove arbitrary objects from
> the distributed
> cache by clicking 'remove' next to the key of the relevant
> object
> displayed on the JSP.
> > The issue is: when we use the unmodified version of
> the code to remove
> an object, the object is successfully removed from the JCS
> remote
> server, but the 'remove' event for that object is not
> broadcast to all
> client machines. Client machines which start up after we
> remove the
> object get 'null' when they try to retrieve the object (the
> desired
> behaviour). However client machines which were already
> running and using
> this object continue to see the object in their view of the
> cache.
> > This problem occurs because the JCSAdminBean (used by
> this JSP) calls
> the wrong API in JCS to remove objects from the cache when
> it's running
> on the remote cache server. It calls the CompositeCache
> API, which is
> intended for use client-side only.
> > Our patches update JCSAdminBean to call this same API
> when its running
> on a client machine, BUT if it's running on a machine on
> which the JCS
> remote server is enabled, it calls the RemoteCacheServer
> API instead.
> > The fix involves replacing 3 methods in
> org.apache.jcs.admin.JCSAdminBean as follows:
> >     /**
> >      * Clears all regions in the
> cache.
> >      * <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 {
> >         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++)
> {
> >             
>    cacheHub.getCache(names[i]).removeAll();
> >             }
> >         }
> >         else {
> >             //
> 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...
> >             
>    // Note: We must do this using reflection
> to bypass
> its package-private access...
> >             
>    Object remoteCacheServerObject =
> RemoteCacheServerFactory.getRemoteCacheServer();
> >             
>    Method removeAllMethod =
> remoteCacheServerObject.getClass().getMethod("removeAll",
> new
> Class[]{String.class});
> >             
>    boolean previouslyAccessibility =
> removeAllMethod.isAccessible();
> >             
>    removeAllMethod.setAccessible(true);
> >             
>    for (int i = 0; i < cacheNames.length;
> i++) {
> >               
>      String cacheName = cacheNames[i];
> >               
>  
>    removeAllMethod.invoke(remoteCacheServerObject,
> new Object[]{cacheName});
> >             
>    }
> >
> removeAllMethod.setAccessible(previouslyAccessibility);
> >             }
> >         
>    catch (Exception e) {
> >             
>    throw new IllegalStateException("Failed to
> remove all
> elements from all cache regions: " + e, e);
> >             }
> >         }
> >     }
> >     /**
> >      * Clears a particular cache
> region.
> >      * <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 {
> >         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)...
> >             
>    // Note: We must do this using reflection
> to bypass
> its package-private access...
> >             
>    Object remoteCacheServerObject =
> RemoteCacheServerFactory.getRemoteCacheServer();
> >             
>    Method removeAllMethod =
> remoteCacheServerObject.getClass().getMethod("removeAll",
> new
> Class[]{String.class});
> >             
>    boolean previouslyAccessibility =
> removeAllMethod.isAccessible();
> >             
>    removeAllMethod.setAccessible(true);
> >             
>    removeAllMethod.invoke(remoteCacheServerObject,
> new
> Object[]{cacheName});
> >
> removeAllMethod.setAccessible(previouslyAccessibility);
> >             }
> >         
>    catch (Exception e) {
> >             
>    throw new IllegalStateException("Failed to
> remove all
> elements from cache region [" + cacheName + "]: " + e, e);
> >             }
> >         }
> >     }
> >     /**
> >      * Removes a particular item from a
> particular region.
> >      * <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 {
> >         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)...
> >             
>    // Note: We must fo this using reflection
> to bypass
> its package-private access...
> >             
>    Object remoteCacheServerObject =
> RemoteCacheServerFactory.getRemoteCacheServer();
> >             
>    Method removeMethod =
> remoteCacheServerObject.getClass().getMethod("remove", new
> Class[]{String.class, Serializable.class});
> >             
>    boolean previouslyAccessibility =
> removeMethod.isAccessible();
> >             
>    removeMethod.setAccessible(true);
> >             
>    removeMethod.invoke(remoteCacheServerObject,
> new
> Object[]{cacheName, keyToRemove});
> >             
>    removeMethod.setAccessible(previouslyAccessibility);
> >             }
> >         
>    catch (Exception e) {
> >             
>    throw new IllegalStateException("Failed to
> remove
> element with key [" + key + ", " + key.getClass() + "] from
> cache region
> [" + cacheName + "]: " + e, e);
> >             }
> >         }
> >     }
> 
> -- 
> This message is automatically generated by JIRA.
> -
> You can reply to this email to add a comment to the issue
> online.
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jcs-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: jcs-dev-help@jakarta.apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jcs-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: jcs-dev-help@jakarta.apache.org
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: jcs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jcs-dev-help@jakarta.apache.org


Mime
View raw message