Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java')
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java227
1 files changed, 227 insertions, 0 deletions
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java
new file mode 100644
index 0000000000..98f0814bc8
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java
@@ -0,0 +1,227 @@
+package org.eclipse.jetty.server.session;
+
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+
+class HashedSession extends AbstractSession
+{
+ private final HashSessionManager _hashSessionManager;
+
+ /** Whether the session has been saved because it has been deemed idle;
+ * in which case its attribute map will have been saved and cleared. */
+ private transient boolean _idled = false;
+
+ /** Whether there has already been an attempt to save this session
+ * which has failed. If there has, there will be no more save attempts
+ * for this session. This is to stop the logs being flooded with errors
+ * due to serialization failures that are most likely caused by user
+ * data stored in the session that is not serializable. */
+ private transient boolean _saveFailed = false;
+
+ /* ------------------------------------------------------------- */
+ protected HashedSession(HashSessionManager hashSessionManager, HttpServletRequest request)
+ {
+ super(hashSessionManager,request);
+ _hashSessionManager = hashSessionManager;
+ }
+
+ /* ------------------------------------------------------------- */
+ protected HashedSession(HashSessionManager hashSessionManager, long created, long accessed, String clusterId)
+ {
+ super(hashSessionManager,created, accessed, clusterId);
+ _hashSessionManager = hashSessionManager;
+ }
+
+ /* ------------------------------------------------------------- */
+ protected void checkValid()
+ {
+ if (_hashSessionManager._idleSavePeriodMs!=0)
+ deIdle();
+ super.checkValid();
+ }
+
+ /* ------------------------------------------------------------- */
+ @Override
+ public void setMaxInactiveInterval(int secs)
+ {
+ super.setMaxInactiveInterval(secs);
+ if (getMaxInactiveInterval()>0&&(getMaxInactiveInterval()*1000/10)<_hashSessionManager._scavengePeriodMs)
+ _hashSessionManager.setScavengePeriod((secs+9)/10);
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ protected void doInvalidate()
+ throws IllegalStateException
+ {
+ super.doInvalidate();
+
+ // Remove from the disk
+ if (_hashSessionManager._storeDir!=null && getId()!=null)
+ {
+ String id=getId();
+ File f = new File(_hashSessionManager._storeDir, id);
+ f.delete();
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ synchronized void save(boolean reactivate)
+ {
+ // Only idle the session if not already idled and no previous save/idle has failed
+ if (!isIdled() && !_saveFailed)
+ {
+ if (Log.isDebugEnabled())
+ Log.debug("Saving {} {}",super.getId(),reactivate);
+
+ File file = null;
+ FileOutputStream fos = null;
+
+ try
+ {
+ file = new File(_hashSessionManager._storeDir, super.getId());
+
+ if (file.exists())
+ file.delete();
+ file.createNewFile();
+ fos = new FileOutputStream(file);
+ willPassivate();
+ save(fos);
+ if (reactivate)
+ didActivate();
+ else
+ clearAttributes();
+ }
+ catch (Exception e)
+ {
+ saveFailed(); // We won't try again for this session
+
+ Log.warn("Problem saving session " + super.getId(), e);
+
+ if (fos != null)
+ {
+ // Must not leave the file open if the saving failed
+ IO.close(fos);
+ // No point keeping the file if we didn't save the whole session
+ file.delete();
+ _idled=false; // assume problem was before _values.clear();
+ }
+ }
+ }
+ }
+ /* ------------------------------------------------------------ */
+ public synchronized void save(OutputStream os) throws IOException
+ {
+ DataOutputStream out = new DataOutputStream(os);
+ out.writeUTF(getClusterId());
+ out.writeUTF(getNodeId());
+ out.writeLong(getCreationTime());
+ out.writeLong(getAccessed());
+
+ /* Don't write these out, as they don't make sense to store because they
+ * either they cannot be true or their value will be restored in the
+ * Session constructor.
+ */
+ //out.writeBoolean(_invalid);
+ //out.writeBoolean(_doInvalidate);
+ //out.writeLong(_maxIdleMs);
+ //out.writeBoolean( _newSession);
+ out.writeInt(getRequests());
+ out.writeInt(getAttributes());
+ ObjectOutputStream oos = new ObjectOutputStream(out);
+ Enumeration<String> e=getAttributeNames();
+ while(e.hasMoreElements())
+ {
+ String key=e.nextElement();
+ oos.writeUTF(key);
+ oos.writeObject(doGet(key));
+ }
+ oos.close();
+ }
+
+ /* ------------------------------------------------------------ */
+ public synchronized void deIdle()
+ {
+ if (isIdled())
+ {
+ // Access now to prevent race with idling period
+ access(System.currentTimeMillis());
+
+
+ if (Log.isDebugEnabled())
+ {
+ Log.debug("Deidling " + super.getId());
+ }
+
+ FileInputStream fis = null;
+
+ try
+ {
+ File file = new File(_hashSessionManager._storeDir, super.getId());
+ if (!file.exists() || !file.canRead())
+ throw new FileNotFoundException(file.getName());
+
+ fis = new FileInputStream(file);
+ _idled = false;
+ _hashSessionManager.restoreSession(fis, this);
+
+ didActivate();
+
+ // If we are doing period saves, then there is no point deleting at this point
+ if (_hashSessionManager._savePeriodMs == 0)
+ file.delete();
+ }
+ catch (Exception e)
+ {
+ Log.warn("Problem deidling session " + super.getId(), e);
+ IO.close(fis);
+ invalidate();
+ }
+ }
+ }
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Idle the session to reduce session memory footprint.
+ *
+ * The session is idled by persisting it, then clearing the session values attribute map and finally setting
+ * it to an idled state.
+ */
+ public synchronized void idle()
+ {
+ save(false);
+ }
+
+ /* ------------------------------------------------------------ */
+ public synchronized boolean isIdled()
+ {
+ return _idled;
+ }
+
+ /* ------------------------------------------------------------ */
+ public synchronized boolean isSaveFailed()
+ {
+ return _saveFailed;
+ }
+
+ /* ------------------------------------------------------------ */
+ public synchronized void saveFailed()
+ {
+ _saveFailed = true;
+ }
+
+} \ No newline at end of file

Back to the top