Simplify expired session cleanup jobs
At present, RedisIndexedHttpSessionConfiguration and JdbcHttpSessionConfiguration include [at]EnableScheduling annotated inner configuration classes that configure expired session cleanup jobs. This approach silently opts in users into general purpose task scheduling support provided by Spring Framework, which isn't something a library should do. Ideally, session cleanup jobs should only require a single thread dedicated to their execution and also one that doesn't compete for resources with general purpose task scheduling. This commit updates RedisIndexedSessionRepository and JdbcIndexedSessionRepository to have them manage their own ThreadPoolTaskScheduler for purposes of running expired session cleanup jobs. Closes gh-2136
This commit is contained in:
@@ -44,6 +44,7 @@ import org.springframework.data.redis.core.BoundValueOperations;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
import org.springframework.session.FlushMode;
|
||||
import org.springframework.session.MapSession;
|
||||
@@ -451,7 +452,7 @@ class RedisIndexedSessionRepositoryTests {
|
||||
Set<Object> expiredIds = new HashSet<>(Arrays.asList("expired-key1", "expired-key2"));
|
||||
given(this.boundSetOperations.members()).willReturn(expiredIds);
|
||||
|
||||
this.redisRepository.cleanupExpiredSessions();
|
||||
this.redisRepository.cleanUpExpiredSessions();
|
||||
|
||||
for (Object id : expiredIds) {
|
||||
String expiredKey = "spring:session:sessions:" + id;
|
||||
@@ -744,6 +745,25 @@ class RedisIndexedSessionRepositoryTests {
|
||||
.withMessage("flushMode cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setCleanupCronNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.redisRepository.setCleanupCron(null))
|
||||
.withMessage("cleanupCron must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setCleanupCronInvalid() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.redisRepository.setCleanupCron("test"))
|
||||
.withMessage("cleanupCron must be valid");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setCleanupCronDisabled() {
|
||||
this.redisRepository.setCleanupCron(Scheduled.CRON_DISABLED);
|
||||
this.redisRepository.afterPropertiesSet();
|
||||
assertThat(this.redisRepository).extracting("taskScheduler").isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void changeRedisNamespace() {
|
||||
String namespace = "foo:bar";
|
||||
|
||||
@@ -117,10 +117,8 @@ class RedisIndexedHttpSessionConfigurationTests {
|
||||
void customCleanupCronAnnotation() {
|
||||
registerAndRefresh(RedisConfig.class, CustomCleanupCronExpressionAnnotationConfiguration.class);
|
||||
|
||||
RedisIndexedHttpSessionConfiguration configuration = this.context
|
||||
.getBean(RedisIndexedHttpSessionConfiguration.class);
|
||||
assertThat(configuration).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "cleanupCron")).isEqualTo(CLEANUP_CRON_EXPRESSION);
|
||||
RedisIndexedSessionRepository sessionRepository = this.context.getBean(RedisIndexedSessionRepository.class);
|
||||
assertThat(sessionRepository).extracting("cleanupCron").isEqualTo(CLEANUP_CRON_EXPRESSION);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user