📄 gigasessionmanager.java
字号:
// ========================================================================// Copyright 2008 Mort Bay Consulting Pty. Ltd.// ------------------------------------------------------------------------// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// ========================================================================package org.mortbay.jetty.openspaces;import java.io.Serializable;import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Timer;import java.util.TimerTask;import java.util.concurrent.ConcurrentHashMap;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;import org.mortbay.jetty.handler.ContextHandler;import org.mortbay.log.Log;import org.mortbay.util.LazyList;import org.openspaces.core.GigaSpace;import org.openspaces.core.GigaSpaceConfigurer;import org.openspaces.core.space.UrlSpaceConfigurer;import org.openspaces.core.space.cache.LocalCacheSpaceConfigurer;import com.gigaspaces.annotation.pojo.SpaceId;import com.gigaspaces.annotation.pojo.SpaceProperty;import com.gigaspaces.annotation.pojo.SpaceRouting;import com.gigaspaces.annotation.pojo.SpaceProperty.IndexType;import com.j_spaces.core.client.Query;import com.j_spaces.core.client.SQLQuery;/** * GigaspacesSessionManager * * A Jetty SessionManager where the session data is stored in a * data grid "cloud". * * On each request, the session data is looked up in the "cloud" * and brought into the local space cache if doesn't already exist, * and an entry put into the managers map of sessions. When the request * exists, any changes, including changes to the access time of the session * are written back out to the grid. * * TODO if we follow this strategy of having the grid store the session * data for us, and it is relatively cheap to access, then we could dispense * with the in-memory _sessions map. */public class GigaSessionManager extends org.mortbay.jetty.servlet.AbstractSessionManager{ private static int __id; //for identifying the scavenger thread private ConcurrentHashMap _sessions; private GigaSpace _space; private String _spaceUrl; private long _waitMsec = 5000L; //wait up to 5secs for requested objects to appear protected Timer _timer; //scavenge timer protected TimerTask _task; //scavenge task protected int _scavengePeriodMs = 1000 * 60 * 10; //10mins protected int _scavengeCount = 0; protected int _savePeriodMs = 60 * 1000; //60 sec protected SQLQuery _query; /** * SessionData * * Data about a session. * * NOTE: we let gigaspaces assign a globally unique identifier for * a SessionData object, although we could compose our own, based on: * canonicalized(contextPath) + virtualhost[0] + sessionid */ public static class SessionData implements Serializable { private String _uid; //unique id private String _id; private long _accessed=-1; private long _lastAccessed=-1; private long _lastSaved=-1; private long _maxIdleMs=-1; private long _cookieSet=-1; private long _created=-1; private ConcurrentHashMap _attributes=null; private String _contextPath; private long _expiryTime=-1; private String _virtualHost; public SessionData () { } public SessionData (String sessionId) { _id=sessionId; _created=System.currentTimeMillis(); _accessed = _created; _lastAccessed = 0; _lastSaved = 0; } @SpaceId(autoGenerate=true) public synchronized String getUid () { return _uid; } public synchronized void setUid (String uid) { _uid=uid; } public synchronized void setId (String id) { _id=id; } @SpaceProperty(index=IndexType.BASIC) @SpaceRouting public synchronized String getId () { return _id; } @SpaceProperty(nullValue="-1") public synchronized long getCreated () { return _created; } public synchronized void setCreated (long ms) { _created = ms; } @SpaceProperty(nullValue="-1") public synchronized long getAccessed () { return _accessed; } public synchronized void setAccessed (long ms) { _accessed = ms; } public synchronized void setLastSaved (long ms) { _lastSaved = ms; } @SpaceProperty(nullValue="-1") public synchronized long getLastSaved () { return _lastSaved; } public synchronized void setMaxIdleMs (long ms) { _maxIdleMs = ms; } @SpaceProperty(nullValue="-1") public synchronized long getMaxIdleMs() { return _maxIdleMs; } public synchronized void setLastAccessed (long ms) { _lastAccessed = ms; } @SpaceProperty(nullValue="-1") public synchronized long getLastAccessed() { return _lastAccessed; } public void setCookieSet (long ms) { _cookieSet = ms; } @SpaceProperty(nullValue="-1") public synchronized long getCookieSet () { return _cookieSet; } @SpaceProperty protected synchronized ConcurrentHashMap getAttributeMap () { return _attributes; } protected synchronized void setAttributeMap (ConcurrentHashMap map) { _attributes = map; } public synchronized void setContextPath(String str) { _contextPath=str; } @SpaceProperty(index=IndexType.BASIC) public synchronized String getContextPath () { return _contextPath; } public synchronized void setExpiryTime (long time) { _expiryTime=time; } @SpaceProperty(nullValue="-1") public synchronized long getExpiryTime () { return _expiryTime; } public synchronized void setVirtualHost (String vhost) { _virtualHost=vhost; } public synchronized String getVirtualHost () { return _virtualHost; } public String toString () { return "Session uid="+_uid+", id="+_id+ ", contextpath="+_contextPath+ ", virtualHost="+_virtualHost+ ",created="+_created+",accessed="+_accessed+ ",lastAccessed="+_lastAccessed+ ",cookieSet="+_cookieSet+ ",expiryTime="+_expiryTime; } public String toStringExtended () { return toString()+"values="+_attributes; } } /** * Session * * A session in memory of a Context. Adds behaviour around SessionData. */ public class Session extends org.mortbay.jetty.servlet.AbstractSessionManager.Session { private SessionData _data; private boolean _dirty=false; /** * Session from a request. * * @param request */ protected Session (HttpServletRequest request) { super(request); _data = new SessionData(_clusterId); _data.setMaxIdleMs(_dftMaxIdleSecs*1000); _data.setContextPath(_context.getContextPath()); _data.setVirtualHost(getVirtualHost(_context)); _data.setExpiryTime(_maxIdleMs < 0 ? 0 : (System.currentTimeMillis() + _maxIdleMs)); _data.setCookieSet(0); if (_data.getAttributeMap()==null) newAttributeMap(); _values=_data.getAttributeMap(); if (Log.isDebugEnabled()) Log.debug("New Session from request, "+_data.toStringExtended()); } /** * Session restored in database. * @param row */ protected Session (SessionData data) { super(data.getCreated(), data.getId()); _data=data; _values = data.getAttributeMap(); if (Log.isDebugEnabled()) Log.debug("New Session from existing session data "+_data.toStringExtended()); } protected void cookieSet() { _data.setCookieSet(_data.getAccessed()); } protected Map newAttributeMap() { if (_data.getAttributeMap()==null) { _data.setAttributeMap(new ConcurrentHashMap()); } return _data.getAttributeMap(); } public void setAttribute (String name, Object value) { super.setAttribute(name, value); _dirty=true; } public void removeAttribute (String name) { super.removeAttribute(name); _dirty=true; } /** * Entry to session. * Called by SessionHandler on inbound request and the session already exists in this node's memory. * * @see org.mortbay.jetty.servlet.AbstractSessionManager.Session#access(long) */ protected void access(long time) { super.access(time); _data.setLastAccessed(_data.getAccessed()); _data.setAccessed(time); _data.setExpiryTime(_maxIdleMs < 0 ? 0 : (time + _maxIdleMs)); } /** * Exit from session * * If the session attributes changed then always write the session * to the cloud. * * If just the session access time changed, we don't always write out the * session, because the gigaspace will serialize the unchanged sesssion * attributes. To save on serialization overheads, we only write out the * session when only the access time has changed if the time at which we * last saved the session exceeds the chosen save interval. * * @see org.mortbay.jetty.servlet.AbstractSessionManager.Session#complete() */ protected void complete() { super.complete(); try { if (_dirty || (_data._accessed - _data._lastSaved) >= (_savePeriodMs)) { _data.setLastSaved(System.currentTimeMillis()); willPassivate(); update(_data); didActivate(); if (Log.isDebugEnabled()) Log.debug("Dirty="+_dirty+", accessed-saved="+_data._accessed +"-"+ _data._lastSaved+", savePeriodMs="+_savePeriodMs); } } catch (Exception e) { Log.warn("Problem persisting changed session data id="+getId(), e); } finally { _dirty=false; } } protected void timeout() throws IllegalStateException { if (Log.isDebugEnabled()) Log.debug("Timing out session id="+getClusterId()); super.timeout(); } protected void willPassivate () { super.willPassivate(); } protected void didActivate () { super.didActivate(); } public String getClusterId() { return super.getClusterId(); } public String getNodeId() { return super.getNodeId(); } } /** * Start the session manager. * * @see org.mortbay.jetty.servlet.AbstractSessionManager#doStart() */ public void doStart() throws Exception { if (_sessionIdManager==null) throw new IllegalStateException("No session id manager defined"); _sessions = new ConcurrentHashMap(); if (_space==null) initSpace(); super.doStart(); _timer=new Timer("GigaspaceSessionScavenger_"+(++__id), true); setScavengePeriod(getScavengePeriod()); } /** * Stop the session manager. * * @see org.mortbay.jetty.servlet.AbstractSessionManager#doStop() */ public void doStop() throws Exception { // stop the scavenger synchronized(this) { if (_task!=null) _task.cancel(); if (_timer!=null) _timer.cancel(); _timer=null; } _sessions.clear(); _sessions = null; _space = null; super.doStop(); } public int getSavePeriod ()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -