View Javadoc

1   package org.eclipse.jetty.nosql;
2   //========================================================================
3   //Copyright (c) 2011 Intalio, Inc.
4   //------------------------------------------------------------------------
5   //All rights reserved. This program and the accompanying materials
6   //are made available under the terms of the Eclipse Public License v1.0
7   //and Apache License v2.0 which accompanies this distribution.
8   //The Eclipse Public License is available at
9   //http://www.eclipse.org/legal/epl-v10.html
10  //The Apache License v2.0 is available at
11  //http://www.opensource.org/licenses/apache2.0.php
12  //You may elect to redistribute this code under either of these licenses.
13  //========================================================================
14  
15  import java.util.ArrayList;
16  import java.util.concurrent.ConcurrentHashMap;
17  import java.util.concurrent.ConcurrentMap;
18  
19  import javax.servlet.http.HttpServletRequest;
20  
21  import org.eclipse.jetty.server.SessionManager;
22  import org.eclipse.jetty.server.session.AbstractSession;
23  import org.eclipse.jetty.server.session.AbstractSessionManager;
24  import org.eclipse.jetty.util.log.Log;
25  import org.eclipse.jetty.util.log.Logger;
26  
27  public abstract class NoSqlSessionManager extends AbstractSessionManager implements SessionManager
28  {
29      private final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");
30  
31      protected final ConcurrentMap<String,NoSqlSession> _sessions=new ConcurrentHashMap<String,NoSqlSession>();
32  
33      private int _stalePeriod=0;
34      private int _savePeriod=0;
35      private int _idlePeriod=-1;
36      private boolean _invalidateOnStop;
37      private boolean _saveAllAttributes;
38      
39      /* ------------------------------------------------------------ */
40      /* (non-Javadoc)
41       * @see org.eclipse.jetty.server.session.AbstractSessionManager#doStart()
42       */
43      @Override
44      public void doStart() throws Exception
45      {
46          super.doStart();
47         
48      }
49      
50      /* ------------------------------------------------------------ */
51      @Override
52      protected void addSession(AbstractSession session)
53      {
54          if (isRunning())
55              _sessions.put(session.getClusterId(),(NoSqlSession)session);
56      }
57  
58      /* ------------------------------------------------------------ */
59      @Override
60      public AbstractSession getSession(String idInCluster)
61      {
62          NoSqlSession session = _sessions.get(idInCluster);
63          
64          __log.debug("getSession: " + session );
65          
66          if (session==null)
67          {
68              session=loadSession(idInCluster);
69              
70              if (session!=null)
71              {
72                  NoSqlSession race=_sessions.putIfAbsent(idInCluster,session);
73                  if (race!=null)
74                  {
75                      session.willPassivate();
76                      session.clearAttributes();
77                      session=race;
78                  }
79              }
80          }
81          
82          return session;
83      }
84      
85      /* ------------------------------------------------------------ */
86      @Override
87      protected void invalidateSessions() throws Exception
88      {
89          // Invalidate all sessions to cause unbind events
90          ArrayList<NoSqlSession> sessions=new ArrayList<NoSqlSession>(_sessions.values());
91          int loop=100;
92          while (sessions.size()>0 && loop-->0)
93          {
94              // If we are called from doStop
95              if (isStopping())
96              {
97                  // Then we only save and remove the session - it is not invalidated.
98                  for (NoSqlSession session : sessions)
99                  {
100                     session.save(false);
101                     removeSession(session,false);
102                 }
103             }
104             else
105             {
106                 for (NoSqlSession session : sessions)
107                     session.invalidate();
108             }
109             
110             // check that no new sessions were created while we were iterating
111             sessions=new ArrayList<NoSqlSession>(_sessions.values());
112         }
113     }
114     
115     /* ------------------------------------------------------------ */
116     @Override
117     protected AbstractSession newSession(HttpServletRequest request)
118     {
119         long created=System.currentTimeMillis();
120         String clusterId=getSessionIdManager().newSessionId(request,created);
121         return new NoSqlSession(this,created,created,clusterId);
122     }
123 
124     /* ------------------------------------------------------------ */
125     @Override
126     protected boolean removeSession(String idInCluster)
127     {
128         synchronized (this)
129         {
130             NoSqlSession session = _sessions.remove(idInCluster);
131 
132             try
133             {
134                 if (session != null)
135                 {
136                     return remove(session);
137                 }
138             }
139             catch (Exception e)
140             {
141                 __log.warn("Problem deleting session id=" + idInCluster,e);
142             }
143 
144             return session != null;
145         }
146     }
147 
148     /* ------------------------------------------------------------ */
149     protected void invalidateSession( String idInCluster )
150     {
151         synchronized (this)
152         {
153             NoSqlSession session = _sessions.remove(idInCluster);
154 
155             try
156             {
157                 if (session != null)
158                 {
159                     remove(session);
160                 }
161             }
162             catch (Exception e)
163             {
164                 __log.warn("Problem deleting session id=" + idInCluster,e);
165             }
166         }
167         
168         /*
169          * ought we not go to cluster and mark it invalid?
170          */
171         
172     }
173     
174     
175     /* ------------------------------------------------------------ */
176     /**
177      * The State Period is the maximum time in seconds that an in memory session is allows to be stale:
178      * <ul>  
179      * <li>If this period is exceeded, the DB will be checked to see if a more recent version is available.</li>
180      * <li>If the state period is set to a value < 0, then no staleness check will be made.</li>
181      * <li>If the state period is set to 0, then a staleness check is made whenever the active request count goes from 0 to 1.</li>
182      * </ul>
183      * @return the stalePeriod in seconds
184      */
185     public int getStalePeriod()
186     {
187         return _stalePeriod;
188     }
189 
190     /* ------------------------------------------------------------ */
191     /**
192      * The State Period is the maximum time in seconds that an in memory session is allows to be stale:
193      * <ul>  
194      * <li>If this period is exceeded, the DB will be checked to see if a more recent version is available.</li>
195      * <li>If the state period is set to a value < 0, then no staleness check will be made.</li>
196      * <li>If the state period is set to 0, then a staleness check is made whenever the active request count goes from 0 to 1.</li>
197      * </ul>
198      * @param stalePeriod the stalePeriod in seconds
199      */
200     public void setStalePeriod(int stalePeriod)
201     {
202         _stalePeriod = stalePeriod;
203     }
204 
205     /* ------------------------------------------------------------ */
206     /**
207      * The Save Period is the time in seconds between saves of a dirty session to the DB.  
208      * When this period is exceeded, the a dirty session will be written to the DB: <ul>
209      * <li>a save period of -2 means the session is written to the DB whenever setAttribute is called.</li>
210      * <li>a save period of -1 means the session is never saved to the DB other than on a shutdown</li>
211      * <li>a save period of 0 means the session is written to the DB whenever the active request count goes from 1 to 0.</li>
212      * <li>a save period of 1 means the session is written to the DB whenever the active request count goes from 1 to 0 and the session is dirty.</li>
213      * <li>a save period of > 1 means the session is written after that period in seconds of being dirty.</li>
214      * </ul>
215      * @return the savePeriod -2,-1,0,1 or the period in seconds >=2 
216      */
217     public int getSavePeriod()
218     {
219         return _savePeriod;
220     }
221 
222     /* ------------------------------------------------------------ */
223     /**
224      * The Save Period is the time in seconds between saves of a dirty session to the DB.  
225      * When this period is exceeded, the a dirty session will be written to the DB: <ul>
226      * <li>a save period of -2 means the session is written to the DB whenever setAttribute is called.</li>
227      * <li>a save period of -1 means the session is never saved to the DB other than on a shutdown</li>
228      * <li>a save period of 0 means the session is written to the DB whenever the active request count goes from 1 to 0.</li>
229      * <li>a save period of 1 means the session is written to the DB whenever the active request count goes from 1 to 0 and the session is dirty.</li>
230      * <li>a save period of > 1 means the session is written after that period in seconds of being dirty.</li>
231      * </ul>
232      * @param savePeriod the savePeriod -2,-1,0,1 or the period in seconds >=2 
233      */
234     public void setSavePeriod(int savePeriod)
235     {
236         _savePeriod = savePeriod;
237     }
238 
239     /* ------------------------------------------------------------ */
240     /**
241      * The Idle Period is the time in seconds before an in memory session is passivated.
242      * When this period is exceeded, the session will be passivated and removed from memory.  If the session was dirty, it will be written to the DB.
243      * If the idle period is set to a value < 0, then the session is never idled.
244      * If the save period is set to 0, then the session is idled whenever the active request count goes from 1 to 0.
245      * @return the idlePeriod
246      */
247     public int getIdlePeriod()
248     {
249         return _idlePeriod;
250     }
251 
252     /* ------------------------------------------------------------ */
253     /**
254      * The Idle Period is the time in seconds before an in memory session is passivated.
255      * When this period is exceeded, the session will be passivated and removed from memory.  If the session was dirty, it will be written to the DB.
256      * If the idle period is set to a value < 0, then the session is never idled.
257      * If the save period is set to 0, then the session is idled whenever the active request count goes from 1 to 0.
258      * @param idlePeriod the idlePeriod in seconds
259      */
260     public void setIdlePeriod(int idlePeriod)
261     {
262         _idlePeriod = idlePeriod;
263     }
264 
265     /* ------------------------------------------------------------ */
266     /**
267      * Invalidate sessions when the session manager is stopped otherwise save them to the DB.
268      * @return the invalidateOnStop
269      */
270     public boolean isInvalidateOnStop()
271     {
272         return _invalidateOnStop;
273     }
274 
275     /* ------------------------------------------------------------ */
276     /**
277      * Invalidate sessions when the session manager is stopped otherwise save them to the DB.
278      * @param invalidateOnStop the invalidateOnStop to set
279      */
280     public void setInvalidateOnStop(boolean invalidateOnStop)
281     {
282         _invalidateOnStop = invalidateOnStop;
283     }
284 
285     /* ------------------------------------------------------------ */
286     /**
287      * Save all attributes of a session or only update the dirty attributes.
288      * @return the saveAllAttributes
289      */
290     public boolean isSaveAllAttributes()
291     {
292         return _saveAllAttributes;
293     }
294 
295     /* ------------------------------------------------------------ */
296     /**
297      * Save all attributes of a session or only update the dirty attributes.
298      * @param saveAllAttributes the saveAllAttributes to set
299      */
300     public void setSaveAllAttributes(boolean saveAllAttributes)
301     {
302         _saveAllAttributes = saveAllAttributes;
303     }
304     
305     /* ------------------------------------------------------------ */
306     abstract protected NoSqlSession loadSession(String clusterId);
307     
308     /* ------------------------------------------------------------ */
309     abstract protected Object save(NoSqlSession session,Object version, boolean activateAfterSave);
310 
311     /* ------------------------------------------------------------ */
312     abstract protected Object refresh(NoSqlSession session, Object version);
313 
314     /* ------------------------------------------------------------ */
315     abstract protected boolean remove(NoSqlSession session);
316     
317 }