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 }