On Aug 26, 2008, at 2:53 PM, Dain Sundstrom wrote:
Gianny,
I recently made some pretty big changes to the interface between the
StatefulContainer and the Cache. I updated the Geronimo integration
to the best of my abilities, but I would really appreciate a review
of the changes. The biggest thing that needs attention is the
WadiCacheTest. I was unable to fully convert this test, because I
don't really understand how the invocation ordering is checked.
One thing I did see while reading the code in Geronimo is the sub-
class of StatefulContainer is redirecting invocations to a remote
server when the instance has been migrated to another server. (For
everyone else reading along, most cache systems will migrate the
session bean instance (the state) to the call instead of migrating
the call to the state as Wadi is doing here). This strategy won't
work properly in OpenEJB because we rely on thread local data such
as the ThreadContext and the current Transaction in the
TransactionManager. The ThreadContext can contain data that is not
serializable (TransactionPolicy) and data that should not be
relocated (Security identity). The real show-stopper is Transaction
which you can not relocate without a distributed TransactionManager
implementation.
I would expect there would be some way to migrate the security
identity.... hopefully all the servers in a cluster have the same idea
about authentication, and this ought to be shareable.
I would expect it to be a lot faster to migrate data than a
transaction, but.... I'm having trouble thinking of how this situation
could arise. What if there's a transaction started where the data
is? When can this happen?
thanks
david jencks
Is there a way to migrate the session back to the call? Otherwise,
you'll have to throw an exception stating that the instance has been
migrated.
-dain
On Aug 26, 2008, at 2:38 PM, Dain Sundstrom wrote:
It is committed. Check it out :)
-dain
On Aug 26, 2008, at 10:41 AM, Dain Sundstrom wrote:
I shelved this work for a few weeks, but got back on it last
night. To start with, I merged the StatefulInstanceManager and
SessionSynchronizationCoordinator into the Stateful container. In
my opinion, this vastly simplifies the code and because all bean
call backs and the general EJB lifecycle is much more visible (and
readable). Then I extracted a simple cache interface from the
container:
public interface Cache<K, V> {
/**
* Add a new entry to the cache. The entry is marked checked-out
and can
* not be accessed again until checked-in.
*
* @IllegalStateException if an value is already associated with
the key
*/
void add(K key, V value);
/**
* Marks the entry checked-out, so this entry can not be accessed
until
* checked-in.
*
* @throws IllegalStateException if the entry is already checked
out.
* @throws Exception if an entry is loaded and the afterLoad
method threw an
* exception
*/
V checkOut(K key) throws Exception;
/**
* Marks the entry available, so it can be accessed again.
*
* @throws IllegalStateException if the entry is not checked out.
*/
void checkIn(K key);
/**
* Removes the entry from the cache.
*/
V remove(K key);
/**
* Removes all of th entries that match the specified filter.
*/
void removeAll(CacheFilter<V> filter);
/**
* Callback listener for cache events.
*/
public interface CacheListener<V> {
/**
* Called after an entry is loaded from a store.
*
* @throws Exception if there is a problem with the instance
*/
void afterLoad(V value) throws Exception;
/**
* Called before an entry is written to a store.
*
* @throws Exception if there is a problem with the instance
*/
void beforeStore(V value) throws Exception;
/**
* Called when an instance has been removed from the cache
due to a
* time-out.
*/
void timedOut(V value);
}
/**
* CacheFileter is used to select values to remove during a
removeAll
* invocation.
*/
public interface CacheFilter<V> {
/**
* True if the filter matches the value.
*/
boolean matches(V v);
}
}
Generally, the container checks out an instance when a method is
invoked, and checks it back in when the transaction completes.
This behavior is due to the Stateful specification that an
instance can not be passivated (e.g., written to disk, distributed
across a cluster, etc.) while in a transaction. The container is
notified when the cache loads or stores an instance so it can make
the proper ejbActivate/ejbPassivate calls.
I believe this interface is simple enough that we can adapt it to
a great verity of cache implementations, but we won't know until
we write some :)
-dain
On Jul 2, 2008, at 3:39 PM, Dain Sundstrom wrote:
Hi all,
I've been thinking about SFSB caching, and have a few ideas about
cache implements I'd like to experiment with like using Java5
concurrent collections, ehCache, ServletSession and maybe
Terracotta. Before I start experimenting, I'm going to try to
simplify the interface between the StatefulContainer and
StatefulInstanceManager (the cache). Right now, if you want to
plugin in a new cache, you have to either write a lot of EJB
specific logic or subclass from our the existing
StatefulInstanceManager, which sucks. My goal is to extract a
simple interface with just a few Map like operations that one
would need to implement to introduce a new cache.
Anyway, just a heads up. I'll post again when I have a initial
draft of the interface available. I'll also try to keep the
existing extensions of StatefulInstanceManager in Geronimo working.
-dain teracotta