Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  //
  //  ========================================================================
  //  Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
  //  ------------------------------------------------------------------------
  //  All rights reserved. This program and the accompanying materials
  //  are made available under the terms of the Eclipse Public License v1.0
  //  and Apache License v2.0 which accompanies this distribution.
  //
  //      The Eclipse Public License is available at
 //      http://www.eclipse.org/legal/epl-v10.html
 //
 //      The Apache License v2.0 is available at
 //      http://www.opensource.org/licenses/apache2.0.php
 //
 //  You may elect to redistribute this code under either of these licenses.
 //  ========================================================================
 //
 
 package org.eclipse.jetty.server.session;
 
 import java.io.File;
 import java.util.Map;
 import java.util.Set;
 
 
 
 
 /* ------------------------------------------------------------ */
An in-memory implementation of SessionManager.

This manager supports saving sessions to disk, either periodically or at shutdown. Sessions can also have their content idle saved to disk to reduce the memory overheads of large idle sessions.

This manager will create it's own Timer instance to scavenge threads, unless it discovers a shared Timer instance set as the "org.eclipse.jetty.server.session.timer" attribute of the ContextHandler.

 
 public class HashSessionManager extends AbstractSessionManager
 {
     final static Logger __log = .;
 
     private static int __id;
     private Timer _timer;
     private boolean _timerStop=false;
     private TimerTask _task;
     long _scavengePeriodMs=30000;
     long _savePeriodMs=0; //don't do period saves by default
     long _idleSavePeriodMs = 0; // don't idle save sessions by default.
     private TimerTask _saveTask;
     File _storeDir;
     private boolean _lazyLoad=false;
     private volatile boolean _sessionsLoaded=false;
     private boolean _deleteUnrestorableSessions=false;
     
 
 
 
     /* ------------------------------------------------------------ */
     public HashSessionManager()
     {
         super();
     }
 
     /* ------------------------------------------------------------ */
     /* (non-Javadoc)
      * @see org.eclipse.jetty.servlet.AbstractSessionManager#doStart()
      */
     @Override
     public void doStart() throws Exception
     {
         super.doStart();
 
         =false;
         ServletContext context = ContextHandler.getCurrentContext();
         if (context!=null)
             =(Timer)context.getAttribute("org.eclipse.jetty.server.session.timer");
         if (==null)
         {
             =true;
             =new Timer("HashSessionScavenger-"+++, true);
         }
 
        if (!=null)
        {
            if (!.exists())
                .mkdirs();
            if (!)
                restoreSessions();
        }
        setSavePeriod(getSavePeriod());
    }
    /* ------------------------------------------------------------ */
    /* (non-Javadoc)
     * @see org.eclipse.jetty.servlet.AbstractSessionManager#doStop()
     */
    @Override
    public void doStop() throws Exception
    {
        // stop the scavengers
        synchronized(this)
        {
            if (!=null)
                .cancel();
            =null;
            if (!=null)
                .cancel();
            =null;
            if (!=null && )
                .cancel();
            =null;
        }
        // This will callback invalidate sessions - where we decide if we will save
        super.doStop();
        .clear();
    }
    /* ------------------------------------------------------------ */
    

Returns:
the period in seconds at which a check is made for sessions to be invalidated.
    public int getScavengePeriod()
    {
        return (int)(/1000);
    }
    /* ------------------------------------------------------------ */
    @Override
    public int getSessions()
    {
        int sessions=super.getSessions();
        if (.isDebugEnabled())
        {
            if (.size()!=sessions)
                .warn("sessions: "+.size()+"!="+sessions);
        }
        return sessions;
    }
    /* ------------------------------------------------------------ */
    

Returns:
seconds Idle period after which a session is saved
    public int getIdleSavePeriod()
    {
      if ( <= 0)
        return 0;
      return (int)( / 1000);
    }
    /* ------------------------------------------------------------ */
    
Configures the period in seconds after which a session is deemed idle and saved to save on session memory. The session is persisted, the values attribute map is cleared and the session set to idled.

Parameters:
seconds Idle period after which a session is saved
    public void setIdleSavePeriod(int seconds)
    {
       = seconds * 1000L;
    }
    /* ------------------------------------------------------------ */
    @Override
    public void setMaxInactiveInterval(int seconds)
    {
        super.setMaxInactiveInterval(seconds);
            setScavengePeriod((+9)/10);
    }
    /* ------------------------------------------------------------ */
    

Parameters:
seconds the period is seconds at which sessions are periodically saved to disk
    public void setSavePeriod (int seconds)
    {
        long period = (seconds * 1000L);
        if (period < 0)
            period=0;
        =period;
        if (!=null)
        {
            synchronized (this)
            {
                if (!=null)
                    .cancel();
                if ( > 0 && !=null//only save if we have a directory configured
                {
                     = new TimerTask()
                    {
                        @Override
                        public void run()
                        {
                            try
                            {
                                saveSessions(true);
                            }
                            catch (Exception e)
                            {
                                .warn(e);
                            }
                        }
                    };
                    .schedule(,,);
                }
            }
        }
    }
    /* ------------------------------------------------------------ */
    

Returns:
the period in seconds at which sessions are periodically saved to disk
    public int getSavePeriod ()
    {
        if (<=0)
            return 0;
        return (int)(/1000);
    }
    /* ------------------------------------------------------------ */
    

Parameters:
seconds the period in seconds at which a check is made for sessions to be invalidated.
    public void setScavengePeriod(int seconds)
    {
        if (seconds==0)
            seconds=60;
        long old_period=;
        long period=seconds*1000L;
        if (period>60000)
            period=60000;
        if (period<1000)
            period=1000;
        =period;
        if (!=null && (period!=old_period || ==null))
        {
            synchronized (this)
            {
                if (!=null)
                    .cancel();
                 = new TimerTask()
                {
                    @Override
                    public void run()
                    {
                        scavenge();
                    }
                };
                .schedule(,,);
            }
        }
    }
    /* -------------------------------------------------------------- */
    
Find sessions that have timed out and invalidate them. This runs in the SessionScavenger thread.
    protected void scavenge()
    {
        //don't attempt to scavenge if we are shutting down
        if (isStopping() || isStopped())
            return;
        Thread thread=Thread.currentThread();
        ClassLoader old_loader=thread.getContextClassLoader();
        try
        {
            if (!=null)
                thread.setContextClassLoader();
            // For each session
            long now=System.currentTimeMillis();
            for (Iterator<HashedSessioni=.values().iterator(); i.hasNext();)
            {
                HashedSession session=i.next();
                long idleTime=session.getMaxInactiveInterval()*1000L;
                if (idleTime>0&&session.getAccessed()+idleTime<now)
                {
                    // Found a stale session, add it to the list
                    session.timeout();
                }
                else if (>0&&session.getAccessed()+<now)
                {
                    session.idle();
                }
            }
        }
        catch (Throwable t)
        {
            .warn("Problem scavenging sessions"t);
        }
        finally
        {
            thread.setContextClassLoader(old_loader);
        }
    }
    /* ------------------------------------------------------------ */
    @Override
    protected void addSession(AbstractSession session)
    {
        if (isRunning())
            .put(session.getClusterId(),(HashedSession)session);
    }
    /* ------------------------------------------------------------ */
    @Override
    public AbstractSession getSession(String idInCluster)
    {
        if (  && !)
        {
            try
            {
                restoreSessions();
            }
            catch(Exception e)
            {
                .warn(e);
            }
        }
        Map<String,HashedSessionsessions=;
        if (sessions==null)
            return null;
        HashedSession session = sessions.get(idInCluster);
        if (session == null && )
            session=restoreSession(idInCluster);
        if (session == null)
            return null;
        if (!=0)
            session.deIdle();
        return session;
    }
    /* ------------------------------------------------------------ */
    @Override
    protected void invalidateSessions() throws Exception
    {
        // Invalidate all sessions to cause unbind events
        ArrayList<HashedSessionsessions=new ArrayList<HashedSession>(.values());
        int loop=100;
        while (sessions.size()>0 && loop-->0)
        {
            // If we are called from doStop
            if (isStopping() &&  != null && .exists() && .canWrite())
            {
                // Then we only save and remove the session - it is not invalidated.
                for (HashedSession session : sessions)
                {
                    session.save(false);
                    removeSession(session,false);
                }
            }
            else
            {
                for (HashedSession session : sessions)
                    session.invalidate();
            }
            // check that no new sessions were created while we were iterating
            sessions=new ArrayList<HashedSession>(.values());
        }
    }
    /* ------------------------------------------------------------ */
    @Override
    protected AbstractSession newSession(HttpServletRequest request)
    {
        return new HashedSession(thisrequest);
    }
    /* ------------------------------------------------------------ */
    protected AbstractSession newSession(long createdlong accessedString clusterId)
    {
        return new HashedSession(thiscreated,accessedclusterId);
    }
    /* ------------------------------------------------------------ */
    @Override
    protected boolean removeSession(String clusterId)
    {
        return .remove(clusterId)!=null;
    }
    /* ------------------------------------------------------------ */
    public void setStoreDirectory (File dir)
    {
        =dir;
    }
    /* ------------------------------------------------------------ */
    public File getStoreDirectory ()
    {
        return ;
    }
    /* ------------------------------------------------------------ */
    public void setLazyLoad(boolean lazyLoad)
    {
         = lazyLoad;
    }
    /* ------------------------------------------------------------ */
    public boolean isLazyLoad()
    {
        return ;
    }
    
    /* ------------------------------------------------------------ */
    public boolean isDeleteUnrestorableSessions()
    {
        return ;
    }
    
    /* ------------------------------------------------------------ */
    public void setDeleteUnrestorableSessions(boolean deleteUnrestorableSessions)
    {
         = deleteUnrestorableSessions;
    }
    /* ------------------------------------------------------------ */
    public void restoreSessions () throws Exception
    {
         = true;
        if (==null || !.exists())
        {
            return;
        }
        if (!.canRead())
        {
            .warn ("Unable to restore Sessions: Cannot read from Session storage directory "+.getAbsolutePath());
            return;
        }
        String[] files = .list();
        for (int i=0;files!=null&&i<files.length;i++)
        {
            restoreSession(files[i]);
        }
    }
    /* ------------------------------------------------------------ */
    protected synchronized HashedSession restoreSession(String idInCuster)
    {
        File file = new File(,idInCuster);
        FileInputStream in = null;
        Exception error = null;
        try
        {
            if (file.exists())
            {
                in = new FileInputStream(file);
                HashedSession session = restoreSession(innull);
                addSession(sessionfalse);
                session.didActivate();
                return session;
            }
        }
        catch (Exception e)
        {
           error = e;
        }
        finally
        {
            if (in != null)
                try {in.close();} catch (Exception x) {.ignore(x);}
            
            if (error != null)
            {
                if (isDeleteUnrestorableSessions() && file.exists())
                {
                    file.delete();
                    .warn("Deleting file for unrestorable session "+idInCustererror);
                }
                else
                    .warn("Problem restoring session "+idInCustererror);
            }
            else
               file.delete(); //delete successfully restored file
                
        }
        return null;
    }
    /* ------------------------------------------------------------ */
    public void saveSessions(boolean reactivatethrows Exception
    {
        if (==null || !.exists())
        {
            return;
        }
        if (!.canWrite())
        {
            .warn ("Unable to save Sessions: Session persistence storage directory "+.getAbsolutePath()+ " is not writeable");
            return;
        }
        for (HashedSession session : .values())
            session.save(true);
    }
    /* ------------------------------------------------------------ */
    public HashedSession restoreSession (InputStream isHashedSession sessionthrows Exception
    {
        /*
         * Take care of this class's fields first by calling
         * defaultReadObject
         */
        DataInputStream in = new DataInputStream(is);
        String clusterId = in.readUTF();
        in.readUTF(); // nodeId
        long created = in.readLong();
        long accessed = in.readLong();
        int requests = in.readInt();
        if (session == null)
            session = (HashedSession)newSession(createdaccessedclusterId);
        session.setRequests(requests);
        int size = in.readInt();
        if (size>0)
        {
            ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(in);
            for (int i=0; i<size;i++)
            {
                String key = ois.readUTF();
                Object value = ois.readObject();
                session.setAttribute(key,value);
            }
            ois.close();
        }
        else
            in.close();
        return session;
    }
    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    protected class ClassLoadingObjectInputStream extends ObjectInputStream
    {
        /* ------------------------------------------------------------ */
        public ClassLoadingObjectInputStream(java.io.InputStream inthrows IOException
        {
            super(in);
        }
        /* ------------------------------------------------------------ */
        public ClassLoadingObjectInputStream () throws IOException
        {
            super();
        }
        /* ------------------------------------------------------------ */
        @Override
        public Class<?> resolveClass (java.io.ObjectStreamClass clthrows IOExceptionClassNotFoundException
        {
            try
            {
                return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader());
            }
            catch (ClassNotFoundException e)
            {
                return super.resolveClass(cl);
            }
        }
    }
New to GrepCode? Check out our FAQ X