/** * Returns a session from the session store, returning null if there's no cached session. * * @param key the session id * @param now the time in milliseconds. now == 0 implies that we're just checking for the * existence of such a session in the cache and do not intend actually to load it if it is * not. * @return the cached session. */ public SessionArrayValue getSession(Env env, String key, long now) { SessionArrayValue session; boolean isNew = false; boolean killSession = false; if (_sessions == null) return null; // Check the cache first session = _sessions.get(key); if (session != null && !session.getId().equals(key)) throw new IllegalStateException(key + " != " + session.getId()); if (session != null) { if (session.inUse()) { System.out.println("USE:" + isNew); return (SessionArrayValue) session.copy(env); } } if (session == null) return null; if (isNew) { isNew = !load(env, session, now); System.out.println("LOAD:" + isNew); } else if (!getSaveOnlyOnShutdown() && !session.load()) { // if the load failed, then the session died out from underneath session.reset(now); isNew = true; } if (!isNew) session.setAccess(now); return (SessionArrayValue) session.copy(env); }
public void saveSession(Env env, SessionArrayValue session) { SessionArrayValue copy = (SessionArrayValue) session.copy(env); _sessions.put(session.getId(), copy); session.finish(); if (_persistentStore != null) { _persistentStore.put(session.getId(), copy.encode(env)); } }
/** * Creates a session. It's already been established that the key does not currently have a * session. */ protected SessionArrayValue create(Env env, String key, long now) { SessionArrayValue session = createSessionValue(key, now, _sessionTimeout); load(env, session, now); // If another thread has created and stored a new session, // putIfNew will return the old session session = _sessions.putIfNew(key, session); if (!key.equals(session.getId())) throw new IllegalStateException(key + " != " + session.getId()); return (SessionArrayValue) session.copy(env); }
/** * Loads the session from the backing store. * * @param session the session to load. * @param now current time in milliseconds. now == 0 implies that we're just checking for the * existence of such a session in the cache and do not intend actually to load it if it is * not. */ protected boolean load(Env env, SessionArrayValue session, long now) { try { if (session.inUse()) { return true; } else if (now <= 0) { return false; } if (_persistentStore != null) { String encoded = (String) _persistentStore.get(session.getId()); if (encoded != null) { session.decode(env, new StringBuilderValue(encoded)); } } if (session.load()) { session.setAccess(now); return true; } else { session.reset(now); } } catch (Exception e) { log.log(Level.FINE, e.toString(), e); session.reset(now); } return false; }
/** Timeout for reaping old sessions. */ public void handleAlarm(Alarm alarm) { try { _sessionList.clear(); int liveSessions = 0; if (_isClosed) return; long now = Alarm.getCurrentTime(); synchronized (_sessions) { _sessionIter = _sessions.values(_sessionIter); while (_sessionIter.hasNext()) { SessionArrayValue session = _sessionIter.next(); long maxIdleTime = session.getMaxInactiveInterval(); if (session.inUse()) liveSessions++; else if (session.getAccessTime() + maxIdleTime < now) _sessionList.add(session); else liveSessions++; } } synchronized (_statisticsLock) { _sessionTimeoutCount += _sessionList.size(); } for (int i = 0; i < _sessionList.size(); i++) { SessionArrayValue session = _sessionList.get(i); try { long maxIdleTime = session.getMaxInactiveInterval(); _sessions.remove(session.getId()); session.invalidate(); } catch (Throwable e) { log.log(Level.FINER, e.toString(), e); } } } finally { if (!_isClosed) alarm.queue(60000); } }
/** Cleans up the sessions when the Application shuts down gracefully. */ public void close() { synchronized (this) { if (_isClosed) return; _isClosed = true; } if (_sessions == null) return; // _alarm.dequeue(); _sessionList.clear(); ArrayList<SessionArrayValue> list = new ArrayList<SessionArrayValue>(); boolean isError = false; synchronized (_sessions) { _sessionIter = _sessions.values(_sessionIter); while (_sessionIter.hasNext()) { SessionArrayValue session = _sessionIter.next(); if (session.isValid()) list.add(session); } } for (int i = list.size() - 1; i >= 0; i--) { SessionArrayValue session = list.get(i); try { if (session.isValid()) { synchronized (session) { if (!session.isEmpty()) session.storeOnShutdown(); } } _sessions.remove(session.getId()); } catch (Exception e) { if (!isError) log.log(Level.WARNING, "Can't store session: " + e, e); isError = true; } } }