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 }