Skip to content

Touch expires key in SortedSetRedisSessionExpirationStore - #3870

Open
lsh1215 wants to merge 1 commit into
spring-projects:3.5.xfrom
lsh1215:fix/gh-3468-sortedset-expires-key
Open

Touch expires key in SortedSetRedisSessionExpirationStore#3870
lsh1215 wants to merge 1 commit into
spring-projects:3.5.xfrom
lsh1215:fix/gh-3468-sortedset-expires-key

Conversation

@lsh1215

@lsh1215 lsh1215 commented Jul 24, 2026

Copy link
Copy Markdown

SortedSetRedisSessionExpirationStore#cleanupExpiredSessions touches the session key (<namespace>:sessions:<id>) instead of the expires shadow key (<namespace>:sessions:expires:<id>).

RedisIndexedSessionRepository#onMessage only handles keyspace events whose key starts with the sessions:expires: prefix. Because the store touches the session key, expiration does not produce an event that matches that prefix, so SessionDeletedEvent and SessionExpiredEvent are not published for sessions tracked by this store. The principal index cleanup and the removal from the expiration sorted set run from that same onMessage handler, so they do not happen either.

This affects RedisIndexedSessionRepository when it is configured with SortedSetRedisSessionExpirationStore. MinuteBasedRedisSessionExpirationStore and the reactive SortedSetReactiveRedisSessionExpirationStore both touch the expires key and are not affected.

Change

cleanupExpiredSessions now touches <namespace>:sessions:expires:<id>, which matches the prefix that onMessage listens on and is consistent with the other two stores. The existing private helper was renamed from getSessionKey to getExpiredKey to reflect the key it builds and to match the naming used in RedisIndexedSessionRepository and ReactiveRedisIndexedSessionRepository.

Testing

  • Updated SortedSetRedisSessionExpirationStoreTests#cleanupExpiredSessionsThenTouchExpiredSessions to assert that the expires key is touched. It fails before the change and passes after.
  • ./gradlew :spring-session-data-redis:test passes.
  • ./gradlew :spring-session-data-redis:integrationTest --tests "*SortedSetRedisSessionExpirationStoreITests" passes.
  • checkstyle and Spring Java Format checks pass for the changed files.

Closes gh-3468

cc @rwinch

cleanupExpiredSessions touched the session key (<namespace>:sessions:<id>)
instead of the expires shadow key (<namespace>:sessions:expires:<id>).
RedisIndexedSessionRepository#onMessage only reacts to key events whose key
starts with the "sessions:expires:" prefix, so touching the session key never
triggered a SessionDeletedEvent/SessionExpiredEvent for sessions tracked by
this store.

Touch the expires key instead, consistent with
MinuteBasedRedisSessionExpirationStore and the reactive
SortedSetReactiveRedisSessionExpirationStore.

Closes spring-projectsgh-3468

Signed-off-by: sanghun <vitash1215@gmail.com>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants