package org.eclipse.jetty.nosql;
//========================================================================
//Copyright (c) 2011 Intalio, Inc.
//------------------------------------------------------------------------
//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.
//========================================================================
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.server.session.AbstractSession;
import org.eclipse.jetty.server.session.AbstractSessionManager;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public abstract class NoSqlSessionManager extends AbstractSessionManager implements SessionManager
{
private final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");
protected final ConcurrentMap<String,NoSqlSession> _sessions=new ConcurrentHashMap<String,NoSqlSession>();
private int _stalePeriod=0;
private int _savePeriod=0;
private int _idlePeriod=-1;
private boolean _invalidateOnStop;
private boolean _saveAllAttributes;
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see org.eclipse.jetty.server.session.AbstractSessionManager#doStart()
*/
@Override
public void doStart() throws Exception
{
super.doStart();
}
/* ------------------------------------------------------------ */
@Override
protected void addSession(AbstractSession session)
{
if (isRunning())
_sessions.put(session.getClusterId(),(NoSqlSession)session);
}
/* ------------------------------------------------------------ */
@Override
public AbstractSession getSession(String idInCluster)
{
NoSqlSession session = _sessions.get(idInCluster);
__log.debug("getSession: " + session );
if (session==null)
{
session=loadSession(idInCluster);
if (session!=null)
{
NoSqlSession race=_sessions.putIfAbsent(idInCluster,session);
if (race!=null)
{
session.willPassivate();
session.clearAttributes();
session=race;
}
}
}
return session;
}
/* ------------------------------------------------------------ */
@Override
protected void invalidateSessions() throws Exception
{
// Invalidate all sessions to cause unbind events
ArrayList<NoSqlSession> sessions=new ArrayList<NoSqlSession>(_sessions.values());
int loop=100;
while (sessions.size()>0 && loop-->0)
{
// If we are called from doStop
if (isStopping())
{
// Then we only save and remove the session - it is not invalidated.
for (NoSqlSession session : sessions)
{
session.save(false);
removeSession(session,false);
}
}
else
{
for (NoSqlSession session : sessions)
session.invalidate();
}
// check that no new sessions were created while we were iterating
sessions=new ArrayList<NoSqlSession>(_sessions.values());
}
}
/* ------------------------------------------------------------ */
@Override
protected AbstractSession newSession(HttpServletRequest request)
{
long created=System.currentTimeMillis();
return new NoSqlSession(this,request);
}
/* ------------------------------------------------------------ */
@Override
protected boolean removeSession(String idInCluster)
{
synchronized (this)
{
NoSqlSession session = _sessions.remove(idInCluster);
try
{
if (session != null)
{
return remove(session);
}
}
catch (Exception e)
{
__log.warn("Problem deleting session id=" + idInCluster,e);
}
return session != null;
}
}
/* ------------------------------------------------------------ */
protected void invalidateSession( String idInCluster )
{
synchronized (this)
{
NoSqlSession session = _sessions.remove(idInCluster);
try
{
if (session != null)
{
remove(session);
}
}
catch (Exception e)
{
__log.warn("Problem deleting session id=" + idInCluster,e);
}
}
/*
* ought we not go to cluster and mark it invalid?
*/
}
/* ------------------------------------------------------------ */
/**
* The State Period is the maximum time in seconds that an in memory session is allows to be stale:
* <ul>
* <li>If this period is exceeded, the DB will be checked to see if a more recent version is available.</li>
* <li>If the state period is set to a value < 0, then no staleness check will be made.</li>
* <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>
* </ul>
* @return the stalePeriod in seconds
*/
public int getStalePeriod()
{
return _stalePeriod;
}
/* ------------------------------------------------------------ */
/**
* The State Period is the maximum time in seconds that an in memory session is allows to be stale:
* <ul>
* <li>If this period is exceeded, the DB will be checked to see if a more recent version is available.</li>
* <li>If the state period is set to a value < 0, then no staleness check will be made.</li>
* <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>
* </ul>
* @param stalePeriod the stalePeriod in seconds
*/
public void setStalePeriod(int stalePeriod)
{
_stalePeriod = stalePeriod;
}
/* ------------------------------------------------------------ */
/**
* The Save Period is the time in seconds between saves of a dirty session to the DB.
* When this period is exceeded, the a dirty session will be written to the DB: <ul>
* <li>a save period of -2 means the session is written to the DB whenever setAttribute is called.</li>
* <li>a save period of -1 means the session is never saved to the DB other than on a shutdown</li>
* <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>
* <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>
* <li>a save period of > 1 means the session is written after that period in seconds of being dirty.</li>
* </ul>
* @return the savePeriod -2,-1,0,1 or the period in seconds >=2
*/
public int getSavePeriod()
{
return _savePeriod;
}
/* ------------------------------------------------------------ */
/**
* The Save Period is the time in seconds between saves of a dirty session to the DB.
* When this period is exceeded, the a dirty session will be written to the DB: <ul>
* <li>a save period of -2 means the session is written to the DB whenever setAttribute is called.</li>
* <li>a save period of -1 means the session is never saved to the DB other than on a shutdown</li>
* <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>
* <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>
* <li>a save period of > 1 means the session is written after that period in seconds of being dirty.</li>
* </ul>
* @param savePeriod the savePeriod -2,-1,0,1 or the period in seconds >=2
*/
public void setSavePeriod(int savePeriod)
{
_savePeriod = savePeriod;
}
/* ------------------------------------------------------------ */
/**
* The Idle Period is the time in seconds before an in memory session is passivated.
* 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.
* If the idle period is set to a value < 0, then the session is never idled.
* If the save period is set to 0, then the session is idled whenever the active request count goes from 1 to 0.
* @return the idlePeriod
*/
public int getIdlePeriod()
{
return _idlePeriod;
}
/* ------------------------------------------------------------ */
/**
* The Idle Period is the time in seconds before an in memory session is passivated.
* 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.
* If the idle period is set to a value < 0, then the session is never idled.
* If the save period is set to 0, then the session is idled whenever the active request count goes from 1 to 0.
* @param idlePeriod the idlePeriod in seconds
*/
public void setIdlePeriod(int idlePeriod)
{
_idlePeriod = idlePeriod;
}
/* ------------------------------------------------------------ */
/**
* Invalidate sessions when the session manager is stopped otherwise save them to the DB.
* @return the invalidateOnStop
*/
public boolean isInvalidateOnStop()
{
return _invalidateOnStop;
}
/* ------------------------------------------------------------ */
/**
* Invalidate sessions when the session manager is stopped otherwise save them to the DB.
* @param invalidateOnStop the invalidateOnStop to set
*/
public void setInvalidateOnStop(boolean invalidateOnStop)
{
_invalidateOnStop = invalidateOnStop;
}
/* ------------------------------------------------------------ */
/**
* Save all attributes of a session or only update the dirty attributes.
* @return the saveAllAttributes
*/
public boolean isSaveAllAttributes()
{
return _saveAllAttributes;
}
/* ------------------------------------------------------------ */
/**
* Save all attributes of a session or only update the dirty attributes.
* @param saveAllAttributes the saveAllAttributes to set
*/
public void setSaveAllAttributes(boolean saveAllAttributes)
{
_saveAllAttributes = saveAllAttributes;
}
/* ------------------------------------------------------------ */
abstract protected NoSqlSession loadSession(String clusterId);
/* ------------------------------------------------------------ */
abstract protected Object save(NoSqlSession session,Object version, boolean activateAfterSave);
/* ------------------------------------------------------------ */
abstract protected Object refresh(NoSqlSession session, Object version);
/* ------------------------------------------------------------ */
abstract protected boolean remove(NoSqlSession session);
}