⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 terracottasessionmanager.java

📁 是离开的肌肤了卡机是离开的就富利卡及是了的开发及拉考试及的福利科技阿斯利康的肌肤莱卡及时的离开福建阿斯顿发
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        // It may happen that one node removes its expired session data,        // so that when this node does the same, the session data is already gone        SessionData sessionData = _sessionDatas.remove(clusterId);        Log.debug("Removed session data {} with id {}", sessionData, clusterId);        // Remove the expiration entry used in scavenging        _sessionExpirations.remove(clusterId);    }    public void setScavengePeriodMs(long ms)    {        ms = ms == 0 ? 60000: ms;        ms = ms > 60000 ? 60000: ms;        ms = ms < 1000 ? 1000: ms;        this._scavengePeriodMs = ms;        scheduleScavenging();    }    public long getScavengePeriodMs()    {        return _scavengePeriodMs;    }    public AbstractSessionManager.Session getSession(String clusterId)    {        Session result = null;        /**         * SESSION LOCKING         * This is an entry point for session locking.         * We lookup the session given the id, and if it exist we hold the lock.         * We unlock on end of method, since this method can be called outside         * an {@link #enter(String)}/{@link #exit(String)} pair.         */        enter(clusterId);        try        {            // Need to synchronize because we use a get-then-put that must be atomic            // on the local session cache            // Refer to method {@link #scavenge()} for an explanation of synchronization order:            // first on _sessions, then on _sessionExpirations.            synchronized (_sessions)            {                result = _sessions.get(clusterId);                if (result == null)                {                    Log.debug("Session with id {} --> local cache miss", clusterId);                    // Lookup the distributed shared sessionData object.                    // This will migrate the session data to this node from the Terracotta server                    // We have not grabbed the distributed lock associated with this session yet,                    // so another node can migrate the session data as well. This is no problem,                    // since just after this method returns the distributed lock will be grabbed by                    // one node, the session data will be changed and the lock released.                    // The second node contending for the distributed lock will then acquire it,                    // and the session data information will be migrated lazily by Terracotta means.                    // We are only interested in having a SessionData reference locally.                    Log.debug("Distributed session data with id {} --> lookup", clusterId);                    SessionData sessionData = _sessionDatas.get(clusterId);                    if (sessionData == null)                    {                        Log.debug("Distributed session data with id {} --> not found", clusterId);                    }                    else                    {                        Log.debug("Distributed session data with id {} --> found", clusterId);                        // Wrap the migrated session data and cache the Session object                        result = new Session(sessionData);                        _sessions.put(clusterId, result);                    }                }                else                {                    Log.debug("Session with id {} --> local cache hit", clusterId);                    if (!_sessionExpirations.containsKey(clusterId))                    {                        // A session is present in the local cache, but it has been expired                        // or invalidated on another node, perform local clean up.                        _sessions.remove(clusterId);                        result = null;                        Log.debug("Session with id {} --> local cache stale");                    }                }            }        }        finally        {            /**             * SESSION LOCKING             */            exit(clusterId);        }        return result;    }    protected String newLockId(String clusterId)    {        StringBuilder builder = new StringBuilder(clusterId);        builder.append(":").append(_contextPath);        builder.append(":").append(_virtualHost);        return builder.toString();    }    // TODO: This method is not needed, only used for testing    public Map getSessionMap()    {        return Collections.unmodifiableMap(_sessions);    }    // TODO: rename to getSessionsCount()    // TODO: also, not used if not by superclass for unused statistics data    public int getSessions()    {        return _sessions.size();    }    protected Session newSession(HttpServletRequest request)    {        /**         * SESSION LOCKING         * This is an entry point for session locking.         * We arrive here when we have to create a new         * session, for a request.getSession(true) call.         */        Session result = new Session(request);        String requestedSessionId = request.getRequestedSessionId();        if (requestedSessionId == null)        {            // Here the user requested a fresh new session, lock it.            enter(result.getClusterId());        }        else        {            if (result.getClusterId().equals(getIdManager().getClusterId(requestedSessionId)))            {                // Here we have a cross context dispatch where the same session id                // is used for two different sessions; we do not lock because the lock                // has already been acquired in enter(Request), based on the requested                // session id.            }            else            {                // Here the requested session id is invalid (the session expired),                // and a new session is created, lock it.                enter(result.getClusterId());            }        }        return result;    }    protected void invalidateSessions()    {        // Do nothing.        // We don't want to remove and invalidate all the sessions,        // because this method is called from doStop(), and just        // because this context is stopping does not mean that we        // should remove the session from any other node (remember        // the session map is shared)    }    private void scavenge()    {        Thread thread = Thread.currentThread();        ClassLoader old_loader = thread.getContextClassLoader();        if (_loader != null) thread.setContextClassLoader(_loader);        try        {            long now = System.currentTimeMillis();            Log.debug(this + " scavenging at {}, scavenge period {}", now, getScavengePeriodMs());            // Detect the candidates that may have expired already, checking the estimated expiration time.            Set<String> candidates = new HashSet<String>();            String lockId = "scavenge:" + _contextPath + ":" + _virtualHost;            Lock.lock(lockId);            try            {                /**                 * Synchronize in order, to avoid deadlocks with method {@link #getSession(String)}.                 * In that method, we first synchronize on _session, then we call _sessionExpirations.containsKey(),                 * which is synchronized by virtue of being a Collection.synchronizedMap.                 * Here we must synchronize in the same order to avoid deadlock.                 */                synchronized (_sessions)                {                    synchronized (_sessionExpirations)                    {                        // Do not use iterators that throw ConcurrentModificationException                        // We do a best effort here, and leave possible imprecisions to the next scavenge                        Enumeration<String> keys = _sessionExpirations.keys();                        while (keys.hasMoreElements())                        {                            String sessionId = keys.nextElement();                            MutableLong value = _sessionExpirations.get(sessionId);                            if (value != null)                            {                                long expirationTime = value.value;                                Log.debug("Estimated expiration time {} for session {}", expirationTime, sessionId);                                if (expirationTime > 0 && expirationTime < now) candidates.add(sessionId);                            }                        }                        _sessions.keySet().retainAll(Collections.list(_sessionExpirations.keys()));                    }                }            }            finally            {                Lock.unlock(lockId);            }            Log.debug("Scavenging detected {} candidate sessions to expire", candidates.size());            // Now validate that the candidates that do expire are really expired,            // grabbing the session lock for each candidate            for (String sessionId : candidates)            {                Session candidate = (Session)getSession(sessionId);                if (candidate == null)                    continue;                                // Here we grab the lock to avoid anyone else interfering                boolean entered = tryEnter(sessionId);                if (entered)                {                    try                    {                        long maxInactiveTime = candidate.getMaxIdlePeriodMs();                        // Exclude sessions that never expire                        if (maxInactiveTime > 0)                        {                            // The lastAccessedTime is fetched from Terracotta, so we're sure it is up-to-date.                            long lastAccessedTime = candidate.getLastAccessedTime();                            // Since we write the shared lastAccessedTime every scavenge period,                            // take that in account before considering the session expired                            long expirationTime = lastAccessedTime + maxInactiveTime + getScavengePeriodMs();                            if (expirationTime < now)                            {                                Log.debug("Scavenging expired session {}, expirationTime {}", candidate.getClusterId(), expirationTime);                                // Calling timeout() result in calling removeSession(), that will clean the data structures                                candidate.timeout();                            }                            else                            {                                Log.debug("Scavenging skipping candidate session {}, expirationTime {}", candidate.getClusterId(), expirationTime);                            }                        }                    }                    finally                    {                        exit(sessionId);                    }                }            }            int sessionCount = getSessions();            if (sessionCount < _minSessions) _minSessions = sessionCount;            if (sessionCount > _maxSessions) _maxSessions = sessionCount;        }        catch (Throwable x)        {            // Must avoid at all costs that the scavenge thread exits, so here we catch and log             if(x instanceof ThreadDeath)                throw (ThreadDeath)x;            Log.warn("Problem scavenging sessions", x);        }        finally        {            thread.setContextClassLoader(old_loader);        }    }    private String canonicalize(String contextPath)    {        if (contextPath == null) return "";        return contextPath.replace('/', '_').replace('.', '_').replace('\\', '_');    }    private String virtualHostFrom(ContextHandler.SContext context)    {        String result = "0.0.0.0";        if (context == null) return result;        String[] vhosts = context.getContextHandler().getVirtualHosts();        if (vhosts == null || vhosts.length == 0 || vhosts[0] == null) return result;        return vhosts[0];    }    class Session extends AbstractSessionManager.Session    {        private static final long serialVersionUID = -2134521374206116367L;        private final SessionData _sessionData;        private long _lastUpdate;        protected Session(HttpServletRequest request)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -