Sachin
Sachin

Reputation: 527

Spring Session - Webflux - Redis Session Clean Up / Evicter - not working

I've followed the main documentation guidance with the following code, for cleaning sessions using Spring Session

@Configuration
@EnableScheduling
internal class RedisCleanUpConfig {

    /**
     * No specific configuration or action should be taken regarding Redis keyspace notifications.
     */
    @Bean
    fun configureReactiveRedisAction(): ConfigureReactiveRedisAction {
        return ConfigureReactiveRedisAction.NO_OP
    }

    /**
     * Disables the default clean up task
     */
    @Bean
    fun reactiveSessionRepositoryCustomizer(): ReactiveSessionRepositoryCustomizer<ReactiveRedisIndexedSessionRepository> {
        return ReactiveSessionRepositoryCustomizer { sessionRepository: ReactiveRedisIndexedSessionRepository ->
            sessionRepository.disableCleanupTask()
        }
    }
}

/**println
 * For cleanup operations (i.e. removing expired session from a ZSet (Sorted Sets) in Redis)
 * Spring's scheduling mechanism will automatically call the cleanup method according to the schedule
 * defined by the @Scheduled annotation.
 */
@Component
internal class SessionEvicter(
    private val redisOperations: ReactiveRedisOperations<String, String>,
    springSessionProperties: SpringSessionProperties,
) {

    private val logger = LoggerFactory.getLogger(SessionEvicter::class.java)

    private val redisKeyLocation = springSessionProperties.redis?.expiredSessionsNameSpace
        ?: "spring:session:sessions:expirations"

    // run every 120 seconds
    @Scheduled(fixedRate = 120, timeUnit = TimeUnit.SECONDS)
    fun cleanup(): Mono<Void> {
        val now = Instant.now()
        val pastFiveMinutes = now.minus(Duration.ofMinutes(5))
        val range = Range.closed(
            (pastFiveMinutes.toEpochMilli()).toDouble(),
            (now.toEpochMilli()).toDouble()
        )
        val limit = Limit.limit().count(500)

        // get the ZSet (Sorted Set) operations
        val zSetOps = redisOperations.opsForZSet()

        return zSetOps.reverseRangeByScore(redisKeyLocation, range, limit)
            .collectList()
            .flatMap { sessionIdsList ->
                if (sessionIdsList.isNotEmpty()) {
                    logger.info("Found ${sessionIdsList.size} sessions to remove.")
                    val removal = zSetOps.remove(
                        redisKeyLocation,
                        *sessionIdsList.toTypedArray()
                    )
                    removal
                } else {
                    logger.info("No sessions found to remove.")
                    Mono.empty()
                }
            }
            .doOnSuccess {
                logger.info("Cleanup operation completed.")
            }
            .doOnError { e ->
                logger.error("Error during cleanup operation: ${e.message}")
            }
            .then()
    }
}

For some reason the sessions don't really get deleted. The sorted set just keeps building up. Is that by design.

I do get a message from Netty server about whether sessions were found to delete or not, very 120s. It always says none were found.

Any ideas where I am maybe wrong?

36 sessions - none have been deleted?

ng

Upvotes: 0

Views: 35

Answers (0)

Related Questions