Skip to content

Commit

Permalink
Remove expired sessionInMap when there is new session in sessionInMap
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Yang committed Feb 14, 2019
1 parent 7799a22 commit 0986c9b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 18 deletions.
44 changes: 35 additions & 9 deletions src/main/java/org/crazycake/shiro/RedisSessionDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ protected Session doReadSession(Serializable sessionId) {
logger.warn("session id is null");
return null;
}
if (this.sessionInMemoryEnabled) {

if (this.sessionInMemoryEnabled) {
Session session = getSessionFromThreadLocal(sessionId);
if (session != null) {
return session;
Expand All @@ -164,14 +165,32 @@ private void setSessionToThreadLocal(Serializable sessionId, Session s) {
sessionMap = new HashMap<Serializable, SessionInMemory>();
sessionsInThread.set(sessionMap);
}

removeExpiredSessionInMemory(sessionMap);

SessionInMemory sessionInMemory = new SessionInMemory();
sessionInMemory.setCreateTime(new Date());
sessionInMemory.setSession(s);
sessionMap.put(sessionId, sessionInMemory);
}

private void removeExpiredSessionInMemory(Map<Serializable, SessionInMemory> sessionMap) {
Iterator<Serializable> it = sessionMap.keySet().iterator();

This comment has been minimized.

Copy link
@timandy

timandy Nov 20, 2019

@alexxiyang 建议遍历 entrySet 比较好

while(it.hasNext()) {
Serializable sessionId = it.next();
SessionInMemory sessionInMemory = sessionMap.get(sessionId);
if (sessionInMemory == null) {
it.remove();
continue;
}
long liveTime = getSessionInMemoryLiveTime(sessionInMemory);
if (liveTime > sessionInMemoryTimeout) {
it.remove();
}
}
}

private Session getSessionFromThreadLocal(Serializable sessionId) {
Session s = null;

if (sessionsInThread.get() == null) {
return null;
Expand All @@ -182,16 +201,19 @@ private Session getSessionFromThreadLocal(Serializable sessionId) {
if (sessionInMemory == null) {
return null;
}
Date now = new Date();
long duration = now.getTime() - sessionInMemory.getCreateTime().getTime();
if (duration < sessionInMemoryTimeout) {
s = sessionInMemory.getSession();
logger.debug("read session from memory");
} else {
long liveTime = getSessionInMemoryLiveTime(sessionInMemory);
if (liveTime > sessionInMemoryTimeout) {
sessionMap.remove(sessionId);
return null;
}

return s;
logger.debug("read session from memory");
return sessionInMemory.getSession();
}

private long getSessionInMemoryLiveTime(SessionInMemory sessionInMemory) {
Date now = new Date();
return now.getTime() - sessionInMemory.getCreateTime().getTime();
}

private String getRedisSessionKey(Serializable sessionId) {
Expand Down Expand Up @@ -253,4 +275,8 @@ public boolean getSessionInMemoryEnabled() {
public void setSessionInMemoryEnabled(boolean sessionInMemoryEnabled) {
this.sessionInMemoryEnabled = sessionInMemoryEnabled;
}

public static ThreadLocal getSessionsInThread() {
return sessionsInThread;
}
}
14 changes: 8 additions & 6 deletions src/test/java/fixture/TestFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@
import java.util.Properties;
import java.util.Set;

import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;

public class TestFixture {

Expand All @@ -42,12 +41,11 @@ public class TestFixture {


public static void blastRedis() {
Jedis jedis = new Jedis(properties.getProperty("redisManager.host").split(":")[0]);
Jedis jedis = doGetRedisInstance();
jedis.flushAll();
jedis.close();
}


// /$$$$$$ /$$$$$$ /$$ /$$
// /$$__ $$ /$$__ $$ | $$ | $$
// /$$$$$$$ /$$$$$$$ /$$$$$$ | $$ \__/| $$ \__//$$$$$$ | $$ /$$$$$$$
Expand Down Expand Up @@ -151,6 +149,10 @@ public static void doChangeSessionName(FakeSession session, String name) {
session.setName(name);
}

private static Jedis doGetRedisInstance() {
return new Jedis(properties.getProperty("redisManager.host").split(":")[0]);
}

// /$$
// | $$
// /$$$$$$ /$$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$
Expand All @@ -161,7 +163,7 @@ public static void doChangeSessionName(FakeSession session, String name) {
// \_______/|_______/|_______/ \_______/|__/ \___/

public static void assertRedisEmpty() {
Jedis jedis = new Jedis(properties.getProperty("redisManager.host").split(":")[0]);
Jedis jedis = doGetRedisInstance();
assertThat("Redis should be empty",jedis.dbSize(), is(0L));
}

Expand Down Expand Up @@ -240,7 +242,7 @@ public static Properties loadProperties(String propFileName) {
}

public static Long getRedisTTL(String key, RedisSerializer keySerializer) {
Jedis jedis = new Jedis(properties.getProperty("redisManager.host").split(":")[0]);
Jedis jedis = doGetRedisInstance();
Long ttl = 0L;
try {
ttl = jedis.ttl(keySerializer.serialize(key));
Expand Down
22 changes: 19 additions & 3 deletions src/test/java/org/crazycake/shiro/RedisSessionDAOTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.crazycake.shiro.exception.SerializationException;
import org.crazycake.shiro.model.FakeSession;
import org.crazycake.shiro.serializer.StringSerializer;
import org.junit.Before;
import org.junit.Test;
import java.util.*;
import static fixture.TestFixture.scaffoldStandaloneRedisManager;
import static org.junit.Assert.fail;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;

import static fixture.TestFixture.*;
import static org.junit.Assert.fail;

public class RedisSessionDAOTest {

Expand Down Expand Up @@ -118,4 +122,16 @@ public void testGetActiveSessions() {
Collection<Session> activeSessions = redisSessionDAO.getActiveSessions();
assertEquals(activeSessions.size(), 2);
}

@Test
public void testRemoveExpiredSessionInMemory() throws InterruptedException, SerializationException {
redisSessionDAO.setSessionInMemoryTimeout(500L);
redisSessionDAO.doCreate(session1);
redisSessionDAO.doReadSession(session1.getId());
Thread.sleep(1000);
redisSessionDAO.doCreate(session2);
redisSessionDAO.doReadSession(session2.getId());
Map<Serializable, SessionInMemory> sessionMap = (Map<Serializable, SessionInMemory>) redisSessionDAO.getSessionsInThread().get();
assertEquals(sessionMap.size(), 1);
}
}

0 comments on commit 0986c9b

Please sign in to comment.