User: jules_gosnell
  Date: 02/01/06 15:54:16

  Modified:    jetty/src/main/org/jboss/jetty
                        DistributedSessionManager.java
  Added:       jetty/src/main/org/jboss/jetty AbstractHttpSessionData.java
  Log:
  abstract out the pieces that need to plug into Sacha's JMX Session stuff
  fix up javadoc for generated code too
  
  Revision  Changes    Path
  1.3       +213 -97   
contrib/jetty/src/main/org/jboss/jetty/DistributedSessionManager.java
  
  Index: DistributedSessionManager.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/contrib/jetty/src/main/org/jboss/jetty/DistributedSessionManager.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DistributedSessionManager.java    2002/01/04 18:21:15     1.2
  +++ DistributedSessionManager.java    2002/01/06 23:54:16     1.3
  @@ -5,11 +5,18 @@
    * See terms of license at gnu.org.
    */
   
  -// $Id: DistributedSessionManager.java,v 1.2 2002/01/04 18:21:15 jules_gosnell Exp $
  +// $Id: DistributedSessionManager.java,v 1.3 2002/01/06 23:54:16 jules_gosnell Exp $
   
  -// A Jetty HttpServer with the interface expected by JBoss'
  -// J2EEDeployer...
  +// TODO
   
  +// 1. abstract out ID allocation and move into DistributedStore
  +// 2. keep all state in HttpSessionState objects
  +// 3. keep all HttpSessionState instances in DistributedStore
  +// 4. we need to know when the data is dirty - will DAOs do this for us ?
  +// 5. we need a handler to flush dirty state to the DistributedStore after each 
request
  +// 6. choice of DistributedStore and frequency of flushing should be parameterisable
  +// 7. remember whether attributes were properly passivated
  +
   package org.jboss.jetty;
   
   import java.rmi.RemoteException;
  @@ -35,56 +42,148 @@
   import org.mortbay.jetty.servlet.ServletHandler;
   import org.mortbay.util.LifeCycle;
   
  -/* --------------------------------------------------------------------- */
  +//----------------------------------------
  +
  +
   /**
  + * An abstraction of a manager for the distributed store of HttpSessions
    *
  - * @version $Id: DistributedSessionManager.java,v 1.2 2002/01/04 18:21:15 
jules_gosnell Exp $
  - * @author [EMAIL PROTECTED]
  + * @author <a href="mailto:jules_gosnell@@yahoo.com";>Jules Gosnell</a>
  + * @version 1.0
  + * @since 1.0
    */
  -public class DistributedSessionManager
  -  extends org.mortbay.jetty.servlet.HashSessionManager
  +interface AbstractDistributedStore
  +{
  +  public String nextId();
  +  public AbstractHttpSessionData make();
  +  public AbstractHttpSessionData get(String id);
  +  public void set(String id, AbstractHttpSessionData data);
  +}
  +
  +//----------------------------------------
  +
  +/**
  + * An implementation of a manager of a CMP based distributed store of HttpSessions
  + *
  + * @author <a href="mailto:jules_gosnell@@yahoo.com";>Jules Gosnell</a>
  + * @version 1.0
  + * @since 1.0
  + * @see AbstractDistributedStore
  + */
  +class EJBDistributedStore
  +  implements AbstractDistributedStore
   {
  -  static InitialContext _jndiContext;
  +  Logger                _log = Logger.getLogger(getClass().getName());
  +  InitialContext        _jndiContext;
  +  CoarseHttpSessionHome _home;
  +  String                _name="ejb/jetty/CoarseHttpSession"; // TODO - parameterise
   
  -  static
  +  EJBDistributedStore()
     {
       try
       {
         _jndiContext=new InitialContext();
  +      Object o=_jndiContext.lookup(_name);
  +      _home=(CoarseHttpSessionHome)PortableRemoteObject.narrow(o, 
CoarseHttpSessionHome.class);
  +      _log.info("Support for EJB-based Distributed HttpSessions loaded: "+_home);
       }
       catch (NamingException e)
       {
  -      Logger.getLogger("DistributedSessionManager").
  -     warn("WARNING: could not get JNDI Context - DistributedSessions are DISABLED");
  +      _log.warn("WARNING: Support for EJB-based Distributed HttpSessions does not 
appear to be loaded");
       }
     }
  -
  -  Logger                     _log;
  -  JBossWebApplicationContext _context;
  -  CoarseHttpSessionHome      _home;
   
  -  DistributedSessionManager(JBossWebApplicationContext context)
  +  /**
  +   * create a new HttpSessionData instance, of the correct type for
  +   * this distributed store
  +   *
  +   */
  +  public AbstractHttpSessionData
  +    make()
     {
  -    super(context.getServletHandler());
  +    return new CoarseHttpSessionData();
  +  }
   
  -    _context=context;
  -    _log    = Logger.getLogger(getClass().getName()+"#" +_context.getContextPath());
  +  /**
  +   * retrieve HttpSessionData from a distributed store
  +   *
  +   * @param id a <code>String</code> value
  +   */
  +  public AbstractHttpSessionData
  +    get(String id)
  +  {
  +    AbstractHttpSessionData data=null;
   
       try
       {
  -      if (_jndiContext!=null)
  -      {
  -     Object o=_jndiContext.lookup("ejb/jetty/CoarseHttpSession"); // TODO - 
parameterise
  -     _home=(CoarseHttpSessionHome)PortableRemoteObject.narrow(o, 
CoarseHttpSessionHome.class);
  -     _log.info("Support for Distributed HttpSessions loaded: "+_home);
  -      }
  +      CoarseHttpSession ejb=_home.findByPrimaryKey(id);
  +      data= ejb.getData();
  +      ejb.remove();
  +      ejb=null;
       }
  -    catch (NamingException e)
  +    catch (RemoteException e)
  +    {}
  +    catch (FinderException e)
  +    {}
  +    catch (RemoveException e)
  +    {}
  +    catch (Exception e)
  +    {}
  +
  +    return data;
  +  }
  +
  +  /**
  +   * submit HttpSessionData to a distributed store
  +   *
  +   * @param id a <code>String</code> value
  +   * @param data an <code>AbstractHttpSessionData</code> value
  +   */
  +  public void
  +    set(String id, AbstractHttpSessionData data)
  +  {
  +    try
       {
  -      _log.warn("WARNING: Support for Distributed HttpSessions does not appear to 
be loaded");
  +      CoarseHttpSession ejb=_home.create((CoarseHttpSessionData)data);
  +      ejb=null;
       }
  +    catch (RemoteException e)
  +    {}
  +    catch (CreateException e)
  +    {}
  +  }
  +
  +  // dummy implementation
  +  static int _nextId=0;
  +
  +  public synchronized String
  +    nextId()
  +  {
  +    return "uid-"+_nextId++;
     }
  +}
   
  +/* --------------------------------------------------------------------- */
  +/**
  + *
  + * @version $Id: DistributedSessionManager.java,v 1.3 2002/01/06 23:54:16 
jules_gosnell Exp $
  + * @author [EMAIL PROTECTED]
  + */
  +public class DistributedSessionManager
  +  extends org.mortbay.jetty.servlet.HashSessionManager
  +{
  +  Logger                          _log;
  +  JBossWebApplicationContext      _context;
  +  static AbstractDistributedStore _manager=new EJBDistributedStore(); // hardwired 
for the moment - TODO
  +
  +  DistributedSessionManager(JBossWebApplicationContext context)
  +  {
  +    super(context.getServletHandler());
  +
  +    _context=context;
  +    _log    =Logger.getLogger(getClass().getName()+"#" +_context.getContextPath());
  +  }
  +
     public HttpSession
       getHttpSession(String id)
     {
  @@ -92,23 +191,8 @@
       HttpSession s = (HttpSession)_sessions.get(id);
   
       // 2. check distributed store
  -    if (s==null && _home!=null)
  -    {
  -      try
  -      {
  -     CoarseHttpSession ejb=_home.findByPrimaryKey(id);
  -     s=new DistributedSession(id, ejb);
  -      }
  -      catch (RemoteException e)
  -      {
  -      }
  -      catch (FinderException e)
  -      {
  -      }
  -      catch (Exception e)
  -      {
  -      }
  -    }
  +    if (s==null && _manager!=null)
  +      s=new DistributedSession(id, _manager.get(id));
   
       return s;
     }
  @@ -130,7 +214,7 @@
     //   {
     //     HttpSession session=super.newHttpSession();
     //     String id=session.getId();
  -  //     _log.info("creating distributed state for session: "+id);
  +  //     _log.info("creating distributed data for session: "+id);
     //     return session;
     //   }
   
  @@ -190,102 +274,134 @@
       // create a completely new session
       DistributedSession()
       {
  -      super();
  +      _id =_manager.nextId();
         _log=Logger.getLogger(getClass().getName()+"#" +getId());
  +      _log.info("new: "+getId());
  +
  +      int dftMaxIdleSecs=_dftMaxIdleSecs;
  +
  +      if (dftMaxIdleSecs>=0)
  +     _maxIdleMs=dftMaxIdleSecs*1000;
       }
   
       // reactivate a passivated session
  -    DistributedSession(String id, CoarseHttpSession ejb)
  +    DistributedSession(String id, AbstractHttpSessionData data)
       {
         _id=id;
         _log=Logger.getLogger(getClass().getName()+"#" +getId());
  +
  +      activate(data);
  +    }
   
  -      activate(ejb);
  +    protected void
  +      activate(AbstractHttpSessionData data)
  +    {
  +      activate(data, true);
       }
   
       protected synchronized void
  -      activate(CoarseHttpSession ejb)
  +      activate(AbstractHttpSessionData data, boolean activateAttributes)
       {
         if (_invalid) throw new IllegalStateException();
   
         _values = new HashMap(11);
  +      _values.putAll(data.getAttributes());
  +      _created    =data.getCreationTime();
  +      _accessed   =data.getLastAccessedTime();
  +      _maxIdleMs  =data.getMaxInactiveInterval()*1000;
  +      _newSession =false;
   
  -      // initialise state from EJB, then remove ejb - in a single transaction...
  -
  -      // this is currently two operations - getData() and remove(). It
  -      // would benefit from being enclosed by a UserTransaction...
  -      try
  -      {
  -     CoarseHttpSessionData data=ejb.getData();
  -
  -     _values.putAll(data.getAttributes());
  -        _created    =data.getCreationTime();
  -        _accessed   =data.getLastAccessedTime();
  -        _maxIdleMs  =data.getMaxInactiveInterval()*1000;
  -        _newSession =false;
  -
  -     _log.info("Session activated: "+ejb);
  -     ejb.remove();
  -     ejb=null;
  -      }
  -      catch (RemoteException e)
  -      {}
  -      catch (RemoveException e)
  -      {}
  -
         // send activate events to listening attributes
  -      if (_values.size()>0)
  +      if (activateAttributes && _values.size()>0)
         {
  +     boolean warn=!data.getAttributesWerePassivated();
        HttpSessionEvent event=new HttpSessionEvent(this);
        Iterator i = _values.values().iterator();
  -     while (i.hasNext())
  -       activateValue(i.next(), event);
  +
  +     try
  +     {
  +       while (i.hasNext())
  +         activateValue(i.next(), event, warn);
  +     }
  +     catch (Exception e)
  +     {
  +       _log.error("Problem whilst activating session attributes", e);
  +     }
         }
  +      _log.info("Session activated: "+getId());
       }
   
       protected void
  -      activateValue(Object attribute, HttpSessionEvent event)
  +      activateValue(Object attribute, HttpSessionEvent event, boolean warn)
       {
         if (attribute!=null && attribute instanceof HttpSessionActivationListener)
  +      {
  +     _log.warn("WARNING: About to activate a session attribute that was not 
passivated: "+attribute);
  +     _log.warn("WARNING: This was probably due to an uncontrolled server 
shutdown.");
        ((HttpSessionActivationListener)attribute)
          .sessionDidActivate(event);
  +      }
       }
   
  -    protected synchronized void
  +    protected void
         passivate()
       {
  +      passivate(true);
  +    }
  +
  +    // PROBLEM: If passivate is going to be called not simply as a
  +    // Session is shutdown, but also during the active life of a
  +    // session, then there is a chance that one request may be
  +    // adding/removing attributes whilst another thread is passivating
  +    // the session.
  +
  +    // how can we prevent this, without throwing a lock around every
  +    // attribute access ?
  +
  +    // I think this is not the only place where concurrency represents
  +    // a threat to the attributes - theseshould all be considered in a
  +    // rationalisation of HttpSession implementations... - Jules
  +
  +    protected synchronized void
  +      passivate(boolean passivateAttributes)
  +    {
         if (_invalid) throw new IllegalStateException();
   
  -      if (_home!=null && _values.size()>0)
  +      if (_manager!=null &&
  +       _values.size()>0)     // not sure about 2nd test - TODO
         {
  -     // send passivate events to listening attributes...
  -     HttpSessionEvent event=new HttpSessionEvent(this);
  -     Iterator i = _values.values().iterator();
  -     while (i.hasNext())
  -       passivateValue(i.next(), event);
  +     if (passivateAttributes)
  +     {
  +       // send passivate events to listening attributes...
  +       HttpSessionEvent event=new HttpSessionEvent(this);
  +       Iterator i = _values.values().iterator();
  +
  +       try
  +       {
  +         while (i.hasNext())
  +           passivateValue(i.next(), event);
  +       }
  +       catch (Exception e)
  +       {
  +         _log.error("Problem whilst passivating session attributes", e);
  +       }
  +     }
   
        // should we bother to remove ourselves from our manager's
        // session list ?
   
  -     // create and EJB and dump state into it - in a single transaction
  -     CoarseHttpSessionData data=new CoarseHttpSessionData();
  +     // create and EJB and dump data into it - in a single transaction
  +     AbstractHttpSessionData data=_manager.make();
        data.setId(getId());
        data.setAttributes(_values);
        data.setCreationTime(getCreationTime());
        data.setLastAccessedTime(getLastAccessedTime());
        data.setMaxInactiveInterval(getMaxInactiveInterval());
  -
  -     try
  -     {
  -       CoarseHttpSession ejb=_home.create(data);
  -       _log.info("Session passivated: "+ejb);
  -       ejb=null;
  -     }
  -     catch (RemoteException e)
  -     {}
  -     catch (CreateException e)
  -     {}
  +     data.setAttributesWerePassivated(passivateAttributes);
  +     _manager.set(getId(), data);
         }
  +
  +      _log.info("Session passivated: "+getId());
       }
   
       protected void
  
  
  
  1.1                  
contrib/jetty/src/main/org/jboss/jetty/AbstractHttpSessionData.java
  
  Index: AbstractHttpSessionData.java
  ===================================================================
  package org.jboss.jetty;
  
  //----------------------------------------
  
  import java.util.Map;
  
  //----------------------------------------
  
  /**
   * An abstraction of the data used for the distributed store of HttpSessions
   *
   * @author <a href="mailto:jules_gosnell@@yahoo.com";>Jules Gosnell</a>
   * @version 1.0
   * @since 1.0
   */
  public interface
    AbstractHttpSessionData
  {
    // from javax.servlet.http.HttpSession
    public long getCreationTime();
    public String getId();
    public long getLastAccessedTime();
    public int getMaxInactiveInterval();
    public void setMaxInactiveInterval(int maxInactiveInterval);
  
    // extra accessors
    public Map getAttributes();
    public void setAttributes(Map attributes);
  
    public void setId(String id);
    public void setCreationTime(long creationTime);
    public void setLastAccessedTime(long lastAccessedTime);
  
    // extra attributes
    public boolean getAttributesWerePassivated();
    public void setAttributesWerePassivated(boolean attributesWerePassivated);
  }
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to