Add Support for background task cleanup of RedisSession

Redis key expiration has no guarantees of when the expired key is
actually removed. In some instances, it is necessary to clean up resources
as soon as the sessione expires. For example, when an HTTP Session expires
we must ensure that the associated Web Socket sessions are closed.

Sessions are now mapped to their expiration times and a background task
is used to clean up the sessions as they expire.

Fixes gh-59
This commit is contained in:
Rob Winch
2014-11-11 20:47:34 -06:00
parent dbc7018a11
commit 6430e43f0e
5 changed files with 372 additions and 69 deletions

View File

@@ -1,6 +1,9 @@
package org.springframework.session.data.redis;
import static org.fest.assertions.Assertions.*;
import static org.fest.assertions.Assertions.assertThat;
import java.io.IOException;
import java.net.ServerSocket;
import org.junit.After;
import org.junit.Before;
@@ -9,24 +12,19 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.session.ExpiringSession;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import redis.embedded.RedisServer;
import java.io.IOException;
import java.net.ServerSocket;
import redis.embedded.RedisServer;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@@ -89,6 +87,7 @@ public class RedisOperationsSessionRepositoryITests<S extends Session> {
}
@Configuration
@EnableRedisHttpSession
static class Config {
@Bean
public JedisConnectionFactory connectionFactory() throws Exception {
@@ -97,20 +96,6 @@ public class RedisOperationsSessionRepositoryITests<S extends Session> {
factory.setUsePool(false);
return factory;
}
@Bean
public RedisTemplate<String,ExpiringSession> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, ExpiringSession> template = new RedisTemplate<String, ExpiringSession>();
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(connectionFactory);
return template;
}
@Bean
public RedisOperationsSessionRepository sessionRepository(RedisTemplate<String, ExpiringSession> redisTemplate) {
return new RedisOperationsSessionRepository(redisTemplate);
}
}
private static Integer availablePort;