Skip to content

Commit

Permalink
Refactored Cache
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfc committed Mar 14, 2011
1 parent 425e585 commit 5feb721
Show file tree
Hide file tree
Showing 27 changed files with 413 additions and 265 deletions.
@@ -1,6 +1,6 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2007, Red Hat Middleware LLC, and individual contributors
* Copyright (c) 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
Expand All @@ -21,17 +21,48 @@
*/
package org.jboss.ejb3.cache;

import org.jboss.ejb3.cache.legacy.StatefulBeanContext;

import javax.ejb.NoSuchEJBException;
import java.io.Serializable;

/**
* Factory for obtaining NoPassivationCache instances
*
* @author <a href="mailto:andrew.rubinger@redhat.com">ALR</a>
* @version $Revision: $
* @author <a href="mailto:cdewolf@redhat.com">Carlo de Wolf</a>
*/
public class NoPassivationCacheFactory implements Ejb3CacheFactory
@Deprecated
public abstract class AbstractLegacyCache implements StatefulCache
{
public StatefulCache createCache()
private StatefulObjectFactory<StatefulBeanContext> factory;

@Override
public StatefulBeanContext create()
{
return create(null, null);
}

@Override
public void discard(Serializable key)
{
return new NoPassivationCache();
remove(key);
}

@Override
public StatefulBeanContext get(Serializable key) throws NoSuchEJBException
{
return get((Object) key);
}

protected abstract void remove(Object key);

@Override
public void remove(Serializable key)
{
remove((Object) key);
}

@Override
public void setStatefulObjectFactory(StatefulObjectFactory<StatefulBeanContext> factory)
{
this.factory = factory;
}
}
32 changes: 21 additions & 11 deletions cache/src/main/java/org/jboss/ejb3/cache/Cache.java
Expand Up @@ -22,28 +22,31 @@
package org.jboss.ejb3.cache;

import javax.ejb.NoSuchEJBException;
import java.io.Serializable;

/**
* Cache a stateful object and make sure any life cycle callbacks are
* called at the appropriate time.
*
* A cache is linked to an object factory. How the link is established is left beyond
* scope.
*
* @author <a href="mailto:carlo.dewolf@jboss.com">Carlo de Wolf</a>
* @version $Revision: $
*/
public interface Cache<T extends Identifiable>
{
/**
* Create a new object.
* Creates and caches a new instance of <code>T</code>.
*
* @param initTypes
* @param initValues
* @return
* @return a new <code>T</code>
*/
T create(Class<?> initTypes[], Object initValues[]);
T create();

/**
* Discard the specified object from cache.
*
* @param key the identifier of the object
*/
void discard(Serializable key);

/**
* Get the specified object from cache. This will mark
* the object as being in use.
Expand All @@ -52,7 +55,7 @@ public interface Cache<T extends Identifiable>
* @return the object
* @throws NoSuchEJBException if the object does not exist
*/
T get(Object key) throws NoSuchEJBException;
T get(Serializable key) throws NoSuchEJBException;

/**
* Peek at an object which might be in use.
Expand All @@ -61,7 +64,7 @@ public interface Cache<T extends Identifiable>
* @return the object
* @throws NoSuchEJBException if the object does not exist
*/
T peek(Object key) throws NoSuchEJBException;
//T peek(Serializable key) throws NoSuchEJBException;

/**
* Release the object from use.
Expand All @@ -75,8 +78,15 @@ public interface Cache<T extends Identifiable>
*
* @param key the identifier of the object
*/
void remove(Object key);
void remove(Serializable key);

/**
* Associate the cache with a stateful object factory.
*
* @param factory the factory this cache should use.
*/
void setStatefulObjectFactory(StatefulObjectFactory<T> factory);

/**
* Start the cache.
*/
Expand Down
4 changes: 3 additions & 1 deletion cache/src/main/java/org/jboss/ejb3/cache/Identifiable.java
Expand Up @@ -21,6 +21,8 @@
*/
package org.jboss.ejb3.cache;

import java.io.Serializable;

/**
* An object that has an identification. How the object obtains
* it's identification is left beyond scope. Could be via construction
Expand All @@ -35,5 +37,5 @@ public interface Identifiable
* The object identifier.
* @return the object identifier
*/
Object getId();
Serializable getId();
}
112 changes: 42 additions & 70 deletions cache/src/main/java/org/jboss/ejb3/cache/NoPassivationCache.java
Expand Up @@ -21,36 +21,30 @@
*/
package org.jboss.ejb3.cache;

import org.jboss.ejb3.cache.legacy.EJBContainer;
import org.jboss.ejb3.cache.legacy.StatefulBeanContext;
import org.jboss.ejb3.cache.legacy.StatefulContainer;

import javax.ejb.EJBException;
import javax.ejb.NoSuchEJBException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
* Comment
*
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
* @version $Revision$
*/
public class NoPassivationCache implements StatefulCache
{
private StatefulContainer container;
private HashMap<Object, StatefulBeanContext> cacheMap;
private int createCount = 0;
private int removeCount = 0;
public class NoPassivationCache<T extends Identifiable> implements Cache<T>
{
private StatefulObjectFactory<T> factory;
private Map<Serializable, T> cacheMap;
private AtomicInteger createCount = new AtomicInteger(0);
private AtomicInteger removeCount = new AtomicInteger(0);
private boolean running;

public void initialize(EJBContainer container) throws Exception
{
this.container = (StatefulContainer) container;
cacheMap = new HashMap<Object, StatefulBeanContext>();
}

public NoPassivationCache()
{
cacheMap = new HashMap<Serializable, T>();
}

public void start()
Expand All @@ -67,22 +61,18 @@ public void stop()
this.running = false;
}

public StatefulBeanContext create()
@Override
public T create()
{
return create(null, null);
}

public StatefulBeanContext create(Class<?>[] initTypes, Object[] initValues)
{
StatefulBeanContext ctx = null;
try
{
ctx = container.create(initTypes, initValues);
++createCount;
T instance = factory.createInstance();
createCount.incrementAndGet();
synchronized (cacheMap)
{
cacheMap.put(ctx.getId(), ctx);
cacheMap.put(instance.getId(), instance);
}
return instance;
}
catch (EJBException e)
{
Expand All @@ -92,67 +82,44 @@ public StatefulBeanContext create(Class<?>[] initTypes, Object[] initValues)
{
throw new EJBException(e);
}
return ctx;
}

public StatefulBeanContext get(Object key) throws EJBException
@Override
public void discard(Serializable key)
{
return get(key, true);
// TODO: can we really do this? it might be a failing pre-destroy?
remove(key);
}

public StatefulBeanContext get(Object key, boolean markInUse) throws EJBException
public T get(Serializable key) throws EJBException
{
StatefulBeanContext entry = null;
synchronized (cacheMap)
{
entry = (StatefulBeanContext) cacheMap.get(key);
}

if (entry == null)
{
throw new NoSuchEJBException("Could not find Stateful bean: " + key);
}

if (markInUse)
{
if (entry.isRemoved())
T instance = cacheMap.get(key);
if(instance == null)
{
throw new NoSuchEJBException("Could not find stateful bean: " + key +
" (bean was marked as removed");
}

entry.setInUse(true);
//entry.lastUsed = System.currentTimeMillis();
throw new NoSuchEJBException("Could not find Stateful bean: " + key);
}
return instance;
}

return entry;
}

public StatefulBeanContext peek(Object key) throws NoSuchEJBException
public void release(T instance)
{
return get(key, false);
}

public void release(StatefulBeanContext ctx)
{
synchronized (ctx)
{
ctx.setInUse(false);
//ctx.lastUsed = System.currentTimeMillis();
}
// do nothing
}

public void remove(Object key)
public void remove(Serializable key)
{
StatefulBeanContext ctx = null;
T instance;
synchronized (cacheMap)
{
ctx = (StatefulBeanContext) cacheMap.remove(key);
instance = cacheMap.remove(key);
if(instance == null)
throw new NoSuchEJBException("Could not find Stateful bean: " + key);
}
if(ctx == null)
throw new NoSuchEJBException("Could not find Stateful bean: " + key);
container.destroy(ctx);
++removeCount;
removeCount.incrementAndGet();
factory.destroyInstance(instance);
}

public int getCacheSize()
Expand All @@ -167,7 +134,7 @@ public int getTotalSize()

public int getCreateCount()
{
return createCount;
return createCount.intValue();
}

public int getPassivatedCount()
Expand All @@ -177,7 +144,7 @@ public int getPassivatedCount()

public int getRemoveCount()
{
return removeCount;
return removeCount.intValue();
}

public int getAvailableCount()
Expand Down Expand Up @@ -206,4 +173,9 @@ public boolean isStarted()
{
return this.running;
}

public void setStatefulObjectFactory(StatefulObjectFactory<T> factory)
{
this.factory = factory;
}
}
29 changes: 15 additions & 14 deletions cache/src/main/java/org/jboss/ejb3/cache/StatefulObjectFactory.java
Expand Up @@ -23,32 +23,33 @@

/**
* Creates and destroys stateful objects.
*
* <p/>
* The object returned by create has dependencies injected. The PostConstruct
* callback, if defined, has been called and the Init callback, if defined,
* has been called.
* callback, if defined, has been called. It'll <b>not<b> call back on the appropriate
* Init method.
*
* @author <a href="mailto:carlo.dewolf@jboss.com">Carlo de Wolf</a>
* @version $Revision: $
*/
public interface StatefulObjectFactory<T>
{
/**
* Creates a new stateful object by calling it's empty constructor,
* do injection, calling post-construct and finally calling the
* appropriate init method.
* Create a new instance of this component. This may be invoked by a component interceptor, a client interceptor,
* or in the course of creating a new client, or in the case of an "eager" singleton, at component start. This
* method will block until the component is available. If the component fails to start then a runtime exception
* will be thrown.
* <p/>
* The instance has been injected and post-construct has been called.
*
* @param initTypes the argument types for the init method
* @param initValues the arguments for the init method
* @return
* @return the component instance
*/
T create(Class<?> initTypes[], Object initValues[]);
T createInstance();

/**
* Perform any cleanup actions on the object, such as
* calling the pre-destroy callback.
* Destroy an instance of the component. This method causes all uninjection and pre-destroy lifecycle invocations
* to occur.
*
* @param obj the object
* @param instance the instance to destroy
*/
void destroy(T obj);
void destroyInstance(T instance);
}

0 comments on commit 5feb721

Please sign in to comment.