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 }