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




Reply via email to