spring-session icon indicating copy to clipboard operation
spring-session copied to clipboard

maxInactiveInterval from JdkMongoSessionConverter is always from MongoSession

Open Lucasark opened this issue 1 year ago • 3 comments

https://github.com/spring-projects/spring-session/blob/a6b97e5913690f01f418a3eb3b36113842ce9de6/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/JdkMongoSessionConverter.java#L66

This attrb is required for create JdkMongoSessionConverter, however is never used to set in the interval.

I know I can set this interval from "@EnableMongoHttpSession", but it is can make confusing when read the documentation

Lucasark avatar Apr 02 '24 08:04 Lucasark

Hi @Lucasark.

The maxInactiveInterval is used if the interval attribute is not present in the Mongo Document when converting it to a MongoSession. I don't quite understand what is the problem here. Would you mind providing more details on where the problem is or what would be the expected behavior?

marcusdacoregio avatar Apr 03 '24 16:04 marcusdacoregio

@marcusdacoregio If I just write this:

@EnableMongoHttpSession
@Configuration(proxyBeanMethods = false)
public class SessionConfig {

    @Bean
    public JdkMongoSessionConverter jdkMongoSessionConverter() {
        return new JdkMongoSessionConverter(Duration.ofMinutes(1));
    }

}

JdkMongoSessionConverter parameter is same of nothing, is not used. I need explicit in EnableMongoHttpSession, even the JdkMongoSessionConverter require 1 parameter

Lucasark avatar Apr 05 '24 04:04 Lucasark

@marcusdacoregio

I recognized the same behavior with the ReactiveMongoSessionRepository and I think the problem is that the MongoSession will be created with a constructor without interval, and AFTERWARDS the maxInactiveInterval will be set. But the constructor already called the setLastAccessedTime method, which will recalculate the expireAt with MapSession.DEFAULT_MAX_INACTIVE_INTERVAL (30m).

To keep it short, every session will have a expireAt date of creationDate + 30m after construction. Setting the maxInteractiveInterval will only have an effect on later setLastAccessedTime calls.

A simple solution would be to use directly the constructor with sessionIdGenerator and maxInactiveInterval instead of calling the constructor without maxInactiveInterval and calling all the setters afterwards.

Code in the ReactiveMongoSessionRepository:

@Override
public Mono<MongoSession> createSession() {
	// @formatter:off
	return Mono.fromSupplier(() -> this.sessionIdGenerator.generate())
	      .map(MongoSession::new)
	      .doOnNext((mongoSession) -> mongoSession.setMaxInactiveInterval(this.defaultMaxInactiveInterval))
	      .doOnNext(
		(mongoSession) -> mongoSession.setSessionIdGenerator(this.sessionIdGenerator))
	      .doOnNext((mongoSession) -> publishEvent(new SessionCreatedEvent(this, mongoSession)))
	      .switchIfEmpty(Mono.just(new MongoSession(this.sessionIdGenerator)))
	      .subscribeOn(Schedulers.boundedElastic())
	      .publishOn(Schedulers.parallel());
       // @formatter:on
}

https://github.com/spring-projects/spring-session/blob/main/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/ReactiveMongoSessionRepository.java#L103-L104

Constructor:

MongoSession(String id, long maxInactiveIntervalInSeconds) {
	this.id = id;
	this.originalSessionId = id;
	this.intervalSeconds = maxInactiveIntervalInSeconds;
	setLastAccessedTime(Instant.ofEpochMilli(this.createdMillis));
}

https://github.com/spring-projects/spring-session/blob/main/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/MongoSession.java#L78

maxedenharter0507 avatar Apr 09 '24 08:04 maxedenharter0507