Hi Dain,
Thanks for having updated the WADI integration code. Over the week-
end, I will have a closer look to the change; update the test; and
perform couple of end-to-end tests within Geronimo.
I agree: invocations cannot be migrated to other servers. It may not
look like it but the code will migrate the session bean instance to
the call. There is indeed some code in WADI which does the reverse
however it is never entered.
Thanks,
Gianny
On 27/08/2008, at 7:53 AM, 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.
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