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         return new NoSqlSession(this,request);
121     }
122 
123     /* ------------------------------------------------------------ */
124     @Override
125     protected boolean removeSession(String idInCluster)
126     {
127         synchronized (this)
128         {
129             NoSqlSession session = _sessions.remove(idInCluster);
130 
131             try
132             {
133                 if (session != null)
134                 {
135                     return remove(session);
136                 }
137             }
138             catch (Exception e)
139             {
140                 __log.warn("Problem deleting session id=" + idInCluster,e);
141             }
142 
143             return session != null;
144         }
145     }
146 
147     /* ------------------------------------------------------------ */
148     protected void invalidateSession( String idInCluster )
149     {
150         synchronized (this)
151         {
152             NoSqlSession session = _sessions.remove(idInCluster);
153 
154             try
155             {
156                 if (session != null)
157                 {
158                     remove(session);
159                 }
160             }
161             catch (Exception e)
162             {
163                 __log.warn("Problem deleting session id=" + idInCluster,e);
164             }
165         }
166         
167         /*
168          * ought we not go to cluster and mark it invalid?
169          */
170         
171     }
172     
173     
174     /* ------------------------------------------------------------ */
175     /**
176      * The State Period is the maximum time in seconds that an in memory session is allows to be stale:
177      * <ul>  
178      * <li>If this period is exceeded, the DB will be checked to see if a more recent version is available.</li>
179      * <li>If the state period is set to a value < 0, then no staleness check will be made.</li>
180      * <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>
181      * </ul>
182      * @return the stalePeriod in seconds
183      */
184     public int getStalePeriod()
185     {
186         return _stalePeriod;
187     }
188 
189     /* ------------------------------------------------------------ */
190     /**
191      * The State Period is the maximum time in seconds that an in memory session is allows to be stale:
192      * <ul>  
193      * <li>If this period is exceeded, the DB will be checked to see if a more recent version is available.</li>
194      * <li>If the state period is set to a value < 0, then no staleness check will be made.</li>
195      * <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>
196      * </ul>
197      * @param stalePeriod the stalePeriod in seconds
198      */
199     public void setStalePeriod(int stalePeriod)
200     {
201         _stalePeriod = stalePeriod;
202     }
203 
204     /* ------------------------------------------------------------ */
205     /**
206      * The Save Period is the time in seconds between saves of a dirty session to the DB.  
207      * When this period is exceeded, the a dirty session will be written to the DB: <ul>
208      * <li>a save period of -2 means the session is written to the DB whenever setAttribute is called.</li>
209      * <li>a save period of -1 means the session is never saved to the DB other than on a shutdown</li>
210      * <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>
211      * <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>
212      * <li>a save period of > 1 means the session is written after that period in seconds of being dirty.</li>
213      * </ul>
214      * @return the savePeriod -2,-1,0,1 or the period in seconds >=2 
215      */
216     public int getSavePeriod()
217     {
218         return _savePeriod;
219     }
220 
221     /* ------------------------------------------------------------ */
222     /**
223      * The Save Period is the time in seconds between saves of a dirty session to the DB.  
224      * When this period is exceeded, the a dirty session will be written to the DB: <ul>
225      * <li>a save period of -2 means the session is written to the DB whenever setAttribute is called.</li>
226      * <li>a save period of -1 means the session is never saved to the DB other than on a shutdown</li>
227      * <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>
228      * <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>
229      * <li>a save period of > 1 means the session is written after that period in seconds of being dirty.</li>
230      * </ul>
231      * @param savePeriod the savePeriod -2,-1,0,1 or the period in seconds >=2 
232      */
233     public void setSavePeriod(int savePeriod)
234     {
235         _savePeriod = savePeriod;
236     }
237 
238     /* ------------------------------------------------------------ */
239     /**
240      * The Idle Period is the time in seconds before an in memory session is passivated.
241      * 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.
242      * If the idle period is set to a value < 0, then the session is never idled.
243      * If the save period is set to 0, then the session is idled whenever the active request count goes from 1 to 0.
244      * @return the idlePeriod
245      */
246     public int getIdlePeriod()
247     {
248         return _idlePeriod;
249     }
250 
251     /* ------------------------------------------------------------ */
252     /**
253      * The Idle Period is the time in seconds before an in memory session is passivated.
254      * 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.
255      * If the idle period is set to a value < 0, then the session is never idled.
256      * If the save period is set to 0, then the session is idled whenever the active request count goes from 1 to 0.
257      * @param idlePeriod the idlePeriod in seconds
258      */
259     public void setIdlePeriod(int idlePeriod)
260     {
261         _idlePeriod = idlePeriod;
262     }
263 
264     /* ------------------------------------------------------------ */
265     /**
266      * Invalidate sessions when the session manager is stopped otherwise save them to the DB.
267      * @return the invalidateOnStop
268      */
269     public boolean isInvalidateOnStop()
270     {
271         return _invalidateOnStop;
272     }
273 
274     /* ------------------------------------------------------------ */
275     /**
276      * Invalidate sessions when the session manager is stopped otherwise save them to the DB.
277      * @param invalidateOnStop the invalidateOnStop to set
278      */
279     public void setInvalidateOnStop(boolean invalidateOnStop)
280     {
281         _invalidateOnStop = invalidateOnStop;
282     }
283 
284     /* ------------------------------------------------------------ */
285     /**
286      * Save all attributes of a session or only update the dirty attributes.
287      * @return the saveAllAttributes
288      */
289     public boolean isSaveAllAttributes()
290     {
291         return _saveAllAttributes;
292     }
293 
294     /* ------------------------------------------------------------ */
295     /**
296      * Save all attributes of a session or only update the dirty attributes.
297      * @param saveAllAttributes the saveAllAttributes to set
298      */
299     public void setSaveAllAttributes(boolean saveAllAttributes)
300     {
301         _saveAllAttributes = saveAllAttributes;
302     }
303     
304     /* ------------------------------------------------------------ */
305     abstract protected NoSqlSession loadSession(String clusterId);
306     
307     /* ------------------------------------------------------------ */
308     abstract protected Object save(NoSqlSession session,Object version, boolean activateAfterSave);
309 
310     /* ------------------------------------------------------------ */
311     abstract protected Object refresh(NoSqlSession session, Object version);
312 
313     /* ------------------------------------------------------------ */
314     abstract protected boolean remove(NoSqlSession session);
315     
316 }