-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
My project uses the spring webflux framework and uses spring-session-data-redis to store sessions.
[project spring version]
Spring-session-core:3.0.0
Spring-session-data-redis:3.0.0
Spring-webflux:6.0.5
[question]
After using @EnableRedisWebSession to enable the use of spring session framework. Checking redis will find that some hashkeys starting with spring:session:sessions: will never expire, that is, ttl = -1. What's going on?
I tried to find the source code and debug it, and found that in the class org.springframework.session.data.redis.ReactiveRedisSessionRepository, when the save() method was called for the first time, the internal saveDelta() executed hmset and expire separately. code show as below:
private Mono<Void> saveDelta() {
if (this.delta.isEmpty()) {
return Mono.empty();
}
String sessionKey = getSessionKey(getId());
Mono<Boolean> update = ReactiveRedisSessionRepository.this.sessionRedisOperations.opsForHash()
.putAll(sessionKey, new HashMap<>(this.delta));
Mono<Boolean> setTtl;
if (getMaxInactiveInterval().getSeconds() >= 0) {
setTtl = ReactiveRedisSessionRepository.this.sessionRedisOperations.expire(sessionKey,
getMaxInactiveInterval());
}
else {
setTtl = ReactiveRedisSessionRepository.this.sessionRedisOperations.persist(sessionKey);
}
return update.and(setTtl).and((s) -> {
this.delta.clear();
s.onComplete();
}).then();
}
You can see that the two monos update.and(setTtl) are executed like this. Could it be that the order is out of order for this reason, causing expire to be executed first and then hmset?
Observing the redis log should be able to prove my guess:
The following is one of the reasons why the key never expires that I found by observing the monitor log of redis:
1696907574.685407 [0 20.205.170.7:36946] "EXPIRE" "spring:session:sessions:e9f5ca03-f6a3-468e-9f79-58c9ff9b2837" "1800"
1696907574.685445 [0 20.205.169.250:27842] "HMSET" "spring:session:sessions:e9f5ca03-f6a3-468e-9f79-58c9ff9b2837" "lastAccessedTime" "1696907574320" "creationTime" "1696907574320" "maxInactiveInterval" "1800"
Finally, execute to check this key, it will indeed never expire:
