All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aspectran.core.component.session.DefaultSessionCache Maven / Gradle / Ivy

There is a newer version: 8.1.5
Show newest version
/*
 * Copyright (c) 2008-2024 The Aspectran Project
 *
 * 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 com.aspectran.core.component.session;

import com.aspectran.utils.ToStringBuilder;
import com.aspectran.utils.logging.Logger;
import com.aspectran.utils.logging.LoggerFactory;
import com.aspectran.utils.thread.AutoLock;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;

/**
 * Implementation of {@code SessionCache}.
 *
 * 

Created: 2017. 6. 24.

*/ public class DefaultSessionCache extends AbstractSessionCache { private static final Logger logger = LoggerFactory.getLogger(DefaultSessionCache.class); /** the cache of sessions in a HashMap */ private final Map sessions = new ConcurrentHashMap<>(); /** Determines the maximum number of concurrent active sessions allowed. */ private volatile int maxActiveSessions; public DefaultSessionCache(SessionHandler sessionHandler, SessionStore sessionStore, boolean clusterEnabled) { super(sessionHandler, sessionStore, clusterEnabled); } @Override public int getMaxActiveSessions() { return maxActiveSessions; } @Override public void setMaxActiveSessions(int maxActiveSessions) { this.maxActiveSessions = maxActiveSessions; } @Override protected DefaultSession doGet(String id) { return (id != null ? sessions.get(id) : null); } @Override protected DefaultSession doPutIfAbsent(String id, DefaultSession session) { AtomicBoolean absent = new AtomicBoolean(false); DefaultSession current = doComputeIfAbsent(id, k -> { absent.set(true); return session; }); return (absent.get() ? null : current); } @Override protected DefaultSession doComputeIfAbsent(String id, Function mappingFunction) { return sessions.computeIfAbsent(id, k -> { checkMaxSessions(id); DefaultSession session = mappingFunction.apply(k); if (session != null) { getStatistics().sessionActivated(); } return session; }); } @Override protected DefaultSession doDelete(String id) { DefaultSession session = sessions.remove(id); if (session != null) { getStatistics().sessionEvicted(); } return session; } @Override protected boolean doReplace(String id, DefaultSession oldValue, DefaultSession newValue) { return sessions.replace(id, oldValue, newValue); } private void checkMaxSessions(String id) { if (maxActiveSessions > 0 && getStatistics().getActiveSessions() >= maxActiveSessions) { getStatistics().sessionRejected(); if (logger.isDebugEnabled()) { logger.debug("Reject session id=" + id + "; Exceeded maximum number of sessions allowed"); } throw new MaxSessionsExceededException(id, maxActiveSessions); } } @Override public Set getActiveSessions() { return new HashSet<>(sessions.keySet()); } @Override public Set getAllSessions() { if (getSessionStore() != null) { return getSessionStore().getAllSessions(); } else { return getActiveSessions(); } } @Override protected void doInitialize() throws Exception { if (getSessionStore() != null) { getSessionStore().initialize(); int restoredSessions = getSessionStore().getAllSessions().size(); if (restoredSessions > 0) { getStatistics().sessionCreated(restoredSessions); if (logger.isDebugEnabled()) { logger.debug("Sessions restored: " + restoredSessions); } } } } @Override protected void doDestroy() throws Exception { // loop over all the sessions in memory (a few times if necessary to catch sessions that have been // added while we're running int loop = 100; while (!sessions.isEmpty() && loop-- >= 0) { for (DefaultSession session : sessions.values()) { // if we have a backing store so give the session to it to write out if necessary if (getSessionStore() != null) { // remove attributes excluded from serialization if (getSessionStore().getNonPersistentAttributes() != null) { for (String name : getSessionStore().getNonPersistentAttributes()) { try { Object old; try (AutoLock ignored = session.lock()) { old = session.getSessionData().setAttribute(name, null); } if (old != null) { session.fireSessionAttributeListeners(name, old, null); } } catch (Exception e) { logger.warn("Failed to remove non-persistent attribute: " + name, e); } } } try { getSessionStore().save(session.getId(), session.getSessionData()); } catch (Exception e) { logger.warn("Failed to save session data of session id=" + session.getId(), e); } doDelete(session.getId()); // remove from memory } else { // not preserving sessions on exit try { session.invalidate(); session.setDestroyedReason(Session.DestroyedReason.UNDEPLOY); } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Session invalidation failed, but ignored", e); } } } } } if (getSessionStore() != null) { getSessionStore().destroy(); } } @Override public String toString() { ToStringBuilder tsb = new ToStringBuilder(); tsb.append("maxActiveSessions", maxActiveSessions); tsb.append("evictionIdleSecs", getEvictionIdleSecs()); tsb.appendForce("saveOnCreate", isSaveOnCreate()); tsb.appendForce("saveOnInactiveEviction", isSaveOnInactiveEviction()); tsb.appendForce("clusterEnabled", isClusterEnabled()); return tsb.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy