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 }