[ https://issues.apache.org/jira/browse/SHIRO-317?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13596478#comment-13596478 ]
Benjamin Marwell edited comment on SHIRO-317 at 2/1/21, 10:32 AM: ------------------------------------------------------------------ In the meantime, I wrote up a DelegatingThreadLocalCache. Now this code might not be perfect, as there were the size, keys and values methods that I don't think ThreadLocal could do, so it just delegates to the actual Cache that is being wrapped. But here is the code, in case you want to use it. {code} package com.whatever.you.need.here; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import java.io.Serializable; import java.util.Collection; import java.util.Set; /** * A simple wrapper Cache that wraps around any cache, where the get will first look if there is an object (typically Session) in thread local and * return it, if not it calls the wrapped cache. */ public class ThreadLocalDelegatingCache implements Cache<Serializable, Serializable> { ThreadLocal<Serializable> sessionThreadLocal = new ThreadLocal<Serializable>(); Cache<Serializable, Serializable> wrappedCache; public void setWrappedCache(Cache wrappedCache) { this.wrappedCache = wrappedCache; } @Override public void clear() throws CacheException { Serializable session = sessionThreadLocal.get(); if (session != null) { sessionThreadLocal.remove(); } wrappedCache.clear(); } @Override public Serializable get(Serializable o) throws CacheException { Serializable session = sessionThreadLocal.get(); if (session != null) { return session; } else { return wrappedCache.get(o); } } @Override public Serializable put(Serializable o, Serializable o2) throws CacheException { Serializable returnValue = wrappedCache.put(o, o2); sessionThreadLocal.set(o2); return returnValue; } @Override public Serializable remove(Serializable o) throws CacheException { Serializable returnValue = wrappedCache.remove(o); sessionThreadLocal.remove(); return returnValue; } @Override public int size() { return wrappedCache.size(); } @Override public Set keys() { return wrappedCache.keys(); } @Override public Collection values() { return wrappedCache.values(); } } {code} was (Author: bytor99999): In the meantime, I wrote up a DelegatingThreadLocalCache. Now this code might not be perfect, as there were the size, keys and values methods that I don't think ThreadLocal could do, so it just delegates to the actual Cache that is being wrapped. But here is the code, in case you want to use it. package com.whatever.you.need.here; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import java.io.Serializable; import java.util.Collection; import java.util.Set; /** * A simple wrapper Cache that wraps around any cache, where the get will first look if there is an object (typically Session) in thread local and * return it, if not it calls the wrapped cache. */ public class ThreadLocalDelegatingCache implements Cache<Serializable, Serializable> { ThreadLocal<Serializable> sessionThreadLocal = new ThreadLocal<Serializable>(); Cache<Serializable, Serializable> wrappedCache; public void setWrappedCache(Cache wrappedCache) { this.wrappedCache = wrappedCache; } @Override public void clear() throws CacheException { Serializable session = sessionThreadLocal.get(); if (session != null) { sessionThreadLocal.remove(); } wrappedCache.clear(); } @Override public Serializable get(Serializable o) throws CacheException { Serializable session = sessionThreadLocal.get(); if (session != null) { return session; } else { return wrappedCache.get(o); } } @Override public Serializable put(Serializable o, Serializable o2) throws CacheException { Serializable returnValue = wrappedCache.put(o, o2); sessionThreadLocal.set(o2); return returnValue; } @Override public Serializable remove(Serializable o) throws CacheException { Serializable returnValue = wrappedCache.remove(o); sessionThreadLocal.remove(); return returnValue; } @Override public int size() { return wrappedCache.size(); } @Override public Set keys() { return wrappedCache.keys(); } @Override public Collection values() { return wrappedCache.values(); } } > 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)