Package wt.cache

Class CacheManager

All Implemented Interfaces:
Serializable, Remote, Unreferenced, wt.cache.CacheServer, wt.util.RemoteStub
Direct Known Subclasses:
ESIDefaultTargetsCache

public class CacheManager extends wt.util.RMIServer implements wt.cache.CacheServer, Unreferenced
A multi-level cache manager service. This is an abstract parent class for specialized object caches. A cache is a fixed size collection of most recently used objects identified by a unique identifier.

This class manages the maintenance and synchronization of multi-level caches where multiple cache objects (usually in separate VMs) have a main/secondary relationship. Updates to a cache are pushed synchronously to the main cache which asynchronously notifies other secondary caches that an entry has been updated.

To be effective, updates to cached objects must notify the cache so that main/secondary caches may receive corresponding updates. It is the responsibility of the application to make this happen.

When a new entry is put into the cache, the entire object is sent to the main cache. When an update call is made, the main is sent only the update. If the main has aged out it's cache entry, it will attempt to retrieve the full object from the secondary.

IMPORTANT NOTE: If your subclass overrides the overflow method, please be aware that after the method returns the cache will preceed to remove whatever object is currently marked as least recently used. This means that if your overflow method changes the state of the cache, the object overflowed may differ from the object passed into the overflow method (e.g. if you call super.remove(key) in the overflow method, after the overflow call returns the cache will proceed to remove what was second least recently used object, now the least recently used after the call to remove).

The follow example is a simple cache of a objects used similarly to how a static Hashtable of object references would be used.

 public class FooManager
 {
    // Foo cache
    private static FooCache fooCache = null;

    // Get/create Foo cache (unsynchronized)
    private static FooCache getFooCache ()
    {
       if (fooCache == null)
           createFooCache();
       return fooCache;
    }

    // Create Foo cache (synchronized)
    private static synchronized void createFooCache ()
    {
       if (fooCache == null)
       {
          try
          {
             fooCache = new FooCache();
          }
          catch (RemoteException e)
          {
             // Fatal - throw as method server exception
             throw new MethodServerException("Unable to create foo cache", e);
          }
       }
    }

    public Foo getFoo (Object foo_key)
    {
       FooCache foo_cache = getFooCache();
       Foo foo = (Foo)foo_cache.get(foo_key);
       if (foo == null)
       {
          // Get or create foo object
          foo = ...

          // Add to foo cache
          foo_cache.put(foo_key, foo);
       }
       return foo;
    }

    public void updateFoo (Foo foo, ...)
    {
       // Do update
       Foo new_foo = ...

       // Update foo cache (required even if new_foo is current cache entry)
       Object foo_key = ...
       getFooCache().put(foo_key, new_foo);
    }
 }

 public class FooCache extends CacheManager
 {
    public FooCache ()
       throws RemoteException
    {
       super();
    }
 }
 
At any given time one server manager in a cluster will be serving as the cache main. If this server manager fails, then another server manager will automatically switch from a subordinate (secondary) role to the cache main role. When this occurs, all existing CacheManager instances within that server manager are "shutdown" and disconnected from cache communications. These instances are then replaced by new instances as needed.

Supported API: true
Extendable: true
See Also:
  • Field Summary

    Fields inherited from class java.rmi.server.RemoteObject

    ref
  • Constructor Summary

    Constructors
    Constructor
    Description
    Construct a cache manager.
    CacheManager(String name, int size, wt.cache.RemoteCacheServer main)
    Deprecated.
  • Method Summary

    Modifier and Type
    Method
    Description
    get(Object key)
    Get cache entry with given key.
    Get desired name of this cache.
    int
    Get desired size of this cache.
    boolean
    Whether this instance has been shutdown.
    void
    put(Object key, Object value)
    Put a cache entry with given key.
    protected void
    putEntry(Object key, Object value)
    Protected method which allows subclasses of CacheManager to take some action when a new entry is being put into the local cache.
    void
    Remove an entry from the cache.
    protected void
    Protected method which allows subclasses of CacheManager to take some action when a entry is being removed from the local cache.
    protected void
    Called on a CacheManager that has been shutdown to allow subclass implementations to provide for a CacheManager's own replacement where this is necessary or where timely replacement is important.
    void
    Reset local cache after main reconnect.
    protected void
    Method intended for override by subclasses that need to do extra cleanup when a CacheManager instance is shut down and replaced.
    void
    update(Object cache_key, Object update_key, Object update_value)
    Notify main and secondary caches of a partial update to a large cache entry.
    protected Object
    updateEntry(Object current_value, Object update_key, Object update_value)
    Perform a partial update to a large cached object.

    Methods inherited from class java.rmi.server.RemoteServer

    getClientHost, getLog, setLog

    Methods inherited from class java.rmi.server.RemoteObject

    equals, getRef, hashCode, toString, toStub

    Methods inherited from class java.lang.Object

    finalize, getClass, notify, notifyAll, wait, wait, wait
  • Constructor Details

    • CacheManager

      public CacheManager() throws RemoteException
      Construct a cache manager.

      The cache name is obtained by calling the getDefaultName method. The cache size if obtained by calling the getDefaultSize method.

      Note that in code executing within the server manager one should never directly construct CacheManager instances. Instead these should always be obtained via ServerManager.getServer(java.lang.String) as only instances returned by this method play their proper role in cache communication.

      Supported API: true

      Throws:
      RemoteException
    • CacheManager

      @Deprecated public CacheManager(String name, int size, wt.cache.RemoteCacheServer main) throws RemoteException
      Deprecated.
      Construct a cache manager. This constructor is available for subclasses that don't rely on the default no-arg constructor.

      Note that in code executing within the server manager one should never directly construct CacheManager instances. Instead these should always be obtained via ServerManager.getServer(java.lang.String) as only instances returned by this method play their proper role in cache communication.

      Supported API: true

      Parameters:
      name - cache name used in debug tracing
      size - maximum number of entries in the cache
      main - RemoteCacheServer used to call main cache (null = no main)
      Throws:
      RemoteException
  • Method Details

    • getDefaultName

      public String getDefaultName()
      Get desired name of this cache. This method returns the last element of the fully qualified class name. Subclasses can override this method to control cache name in some other way.

      Supported API: true
    • getDefaultSize

      public int getDefaultSize()
      Get desired size of this cache. This method attempts to find a size property called wt.cache.size.CacheName where cacheName is the name of this cache. Subclasses can override this method to control cache size in some other way. If no property is found, the default size is 100.

      Supported API: true
    • reset

      public void reset() throws RemoteException
      Reset local cache after main reconnect.

      Called after recovery from communication failure when a connection to a new main has been established. The current cache contents are cleared and the local cache is registered as a secondary of the new main.

      This may be called as a result of calling other cache updating operations since that is when the disconnect and reconnect may take place. When this happens, this method is called before the other methods return.

      NOTE: Any subclass overriding this method must be sure to call super.reset() in all cases from within the override method, otherwise the cache will not recover properly after communication failures.

      Supported API: true

      Throws:
      RemoteException
    • get

      public Object get(Object key)
      Get cache entry with given key. If not in local cache, the main cache is checked.

      Supported API: true
      Parameters:
      key - the key object
      Returns:
      the corresponding cached object or null if not in cache
    • put

      public void put(Object key, Object value)
      Put a cache entry with given key. The entry will also be put in the main cache, and any secondary caches will have their corresponding entry removed.

      Supported API: true
      Parameters:
      key - the key object
      value - the value object
    • putEntry

      protected void putEntry(Object key, Object value)
      Protected method which allows subclasses of CacheManager to take some action when a new entry is being put into the local cache. This method is invoked to put the entry in the local cache as a result of a local put call or a call forwarded from a secondary cache or when a local get call downloads the entry from a main cache. If this cache has a main cache, the put call will already be forwarded to the main before this method is invoked. Secondary caches will be notified to remove their entries after this method returns. This method must not cause a recursive put call.

      Supported API: true
      Parameters:
      key - the key object
      value - the value object
    • update

      public void update(Object cache_key, Object update_key, Object update_value)
      Notify main and secondary caches of a partial update to a large cache entry. The existing main cache object will be updated with a call to updateEntry. Any secondary caches will have their corresponding entry removed. Subclasses should override updateEntry to implement partial updates for large objects.

      The caller is expected to have already updated the local cache entry before this method is called.

      Supported API: true

      Parameters:
      cache_key - the key for the cache entry
      update_key - the key for what is being updated in the entry
      update_value - the updated value
    • updateEntry

      protected Object updateEntry(Object current_value, Object update_key, Object update_value)
      Perform a partial update to a large cached object. Subclasses should override. This implementation assumes update_value is the new cache value. This method is called after a update method is performed in a secondary cache. It must not cause a recursive update call.

      Supported API: true
      Parameters:
      current_value - the current value for the cache entry
      update_key - the key for what is being updated in the entry
      update_value - the new value for whatever is being updated in the entry
      Returns:
      the updated value of the overall cache entry
    • remove

      public void remove(Object key)
      Remove an entry from the cache. The entry is also removed from the main cache and any secondary caches. This is similar to put.(key, null) but it does not result in a null entry taking up space in the cache.

      Supported API: true
      Parameters:
      key - the key object (null = clear entire cache)
    • removeEntry

      protected void removeEntry(Object key)
      Protected method which allows subclasses of CacheManager to take some action when a entry is being removed from the local cache. This method is invoked to remove the entry in the local cache as a result of a local remove call or a call forwarded from a main cache. If this cache has a main cache, the remove call will already be forwarded to the main before this method is invoked. Secondary caches will be notified to remove their entries after this method returns. This method must not cause a recursive remove call.

      This method is not called when entries are being removed by the overflow or reset methods.

      Supported API: true

      Parameters:
      key - the key object (null = clear entire cache)
    • isShutdown

      public boolean isShutdown()
      Whether this instance has been shutdown. Primarily exposed for troubleshooting purposes.

      Supported API: true
    • shutdownInstance

      protected void shutdownInstance()
      Method intended for override by subclasses that need to do extra cleanup when a CacheManager instance is shut down and replaced. Note that calling this will neither fully shut down an instance nor cause isShutdown() to return true. Rather this method serves as a callback for special class-specific shutdown needs from within the overall shutdown process.

      CacheManager instances are shutdown and replaced within the server manager whenever a server manager changes between main and subordinate (secondary) states.

      Supported API: true

    • replaceInstance

      protected void replaceInstance()
      Called on a CacheManager that has been shutdown to allow subclass implementations to provide for a CacheManager's own replacement where this is necessary or where timely replacement is important.

      CacheManager instances are shutdown and replaced within the server manager whenever a server manager changes between main and subordinate (secondary) states.

      It should rarely be necessary to override this method as shutdown CacheManager instances automatically replaced on demand upon ServerManager.getServer(java.lang.String) calls.

      Supported API: true