[
https://issues.apache.org/jira/browse/SHIRO-317?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13608368#comment-13608368
]
Benjamin Marwell edited comment on SHIRO-317 at 2/1/21, 9:20 AM:
-----------------------------------------------------------------
{code}
package com.blah.account.security.shiro.cache;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.subject.PrincipalCollection;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* User: Mark Spritzler
*
* First Serializable is the Key in the cache
* Second Serializable is the Session object.
*
*/
public class ConcurrentHashMapDelegatingCache implements Cache<Serializable,
Serializable> {
Cache<Serializable, Serializable> wrappedCache;
private static ConcurrentHashMap<Serializable, Serializable> sessions = new
ConcurrentHashMap<>();
public void setWrappedCache(Cache<Serializable, Serializable> wrappedCache) {
this.wrappedCache = wrappedCache;
}
@Override
public void clear() throws CacheException {
wrappedCache.clear();
}
// Parameter is the SessionId to find in the cache object.
@Override
public Serializable get(Serializable o) throws CacheException {
Serializable session = getSessionFromMap(o);
if (session != null) {
return session;
} else {
session = wrappedCache.get(o);
setSessionInMap(o, session);
return session;
}
}
// Parameters are key and value to put into the Session
@Override
public Serializable put(Serializable key, Serializable session) throws
CacheException {
Serializable currentSession = getSessionFromMap(key);
if (currentSession != null) {
// Check to see if there are any changes, if not, why put into Cache again
if (currentSession.equals(session)) {
return currentSession;
}
}
Serializable returnValue = wrappedCache.put(key, session);
setSessionInMap(key, session);
return returnValue;
}
@Override
public Serializable remove(Serializable key) throws CacheException {
Serializable returnValue;
if (key instanceof PrincipalCollection) {
String primaryPrincipal = (String)((PrincipalCollection)
key).getPrimaryPrincipal();
// Will need to find someway to convert this to a sessionId
returnValue = wrappedCache.remove(primaryPrincipal);
removeSessionFromMap(primaryPrincipal);
} else {
returnValue = wrappedCache.remove(key);
removeSessionFromMap(key);
}
return returnValue;
}
@Override
public int size() {
return wrappedCache.size();
}
@Override
public Set<Serializable> keys() {
return wrappedCache.keys();
}
@Override
public Collection<Serializable> values() {
return wrappedCache.values();
}
public static Serializable getSessionFromMap(Serializable key) {
return sessions.get(key);
}
public static void setSessionInMap(Serializable key, Serializable session) {
sessions.put(key, session);
}
public static void removeSessionFromMap(Serializable key) {
sessions.remove(key);
}
}
{code}
was (Author: bytor99999):
package com.blah.account.security.shiro.cache;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.subject.PrincipalCollection;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* User: Mark Spritzler
*
* First Serializable is the Key in the cache
* Second Serializable is the Session object.
*
*/
public class ConcurrentHashMapDelegatingCache implements Cache<Serializable,
Serializable> {
Cache<Serializable, Serializable> wrappedCache;
private static ConcurrentHashMap<Serializable, Serializable> sessions = new
ConcurrentHashMap<>();
public void setWrappedCache(Cache<Serializable, Serializable> wrappedCache) {
this.wrappedCache = wrappedCache;
}
@Override
public void clear() throws CacheException {
wrappedCache.clear();
}
// Parameter is the SessionId to find in the cache object.
@Override
public Serializable get(Serializable o) throws CacheException {
Serializable session = getSessionFromMap(o);
if (session != null) {
return session;
} else {
session = wrappedCache.get(o);
setSessionInMap(o, session);
return session;
}
}
// Parameters are key and value to put into the Session
@Override
public Serializable put(Serializable key, Serializable session) throws
CacheException {
Serializable currentSession = getSessionFromMap(key);
if (currentSession != null) {
// Check to see if there are any changes, if not, why put into Cache again
if (currentSession.equals(session)) {
return currentSession;
}
}
Serializable returnValue = wrappedCache.put(key, session);
setSessionInMap(key, session);
return returnValue;
}
@Override
public Serializable remove(Serializable key) throws CacheException {
Serializable returnValue;
if (key instanceof PrincipalCollection) {
String primaryPrincipal = (String)((PrincipalCollection)
key).getPrimaryPrincipal();
// Will need to find someway to convert this to a sessionId
returnValue = wrappedCache.remove(primaryPrincipal);
removeSessionFromMap(primaryPrincipal);
} else {
returnValue = wrappedCache.remove(key);
removeSessionFromMap(key);
}
return returnValue;
}
@Override
public int size() {
return wrappedCache.size();
}
@Override
public Set<Serializable> keys() {
return wrappedCache.keys();
}
@Override
public Collection<Serializable> values() {
return wrappedCache.values();
}
public static Serializable getSessionFromMap(Serializable key) {
return sessions.get(key);
}
public static void setSessionInMap(Serializable key, Serializable session) {
sessions.put(key, session);
}
public static void removeSessionFromMap(Serializable key) {
sessions.remove(key);
}
}
> Read session from cache once per request
> ----------------------------------------
>
> Key: SHIRO-317
> URL: https://issues.apache.org/jira/browse/SHIRO-317
> Project: Shiro
> Issue Type: New Feature
> Affects Versions: 1.1.0, 1.2.0, 1.2.1
> Reporter: Luke Biddell
> Assignee: Les Hazlewood
> Priority: Minor
>
> As per our discussion on the mailing thread, I've wired up my sessions to be
> stored in memcached (membase in the longer term). On a per request basis I'm
> seeing approximately 5 hits on my cache to retrieve the session. I would
> expect to see only one hit per threaded request, with the session stored as a
> thread local.
> For distributed caches this saves on network calls and for local caches it
> will save on potential lock contention.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)