Clarify behavior of WebSession#save()

+ minor update to the InMemoryWebSession to match the defined behavior.

Issue: SPR-17051
This commit is contained in:
Rossen Stoyanchev
2018-07-18 22:11:08 -04:00
parent 66d73017d5
commit 9498da5910
3 changed files with 66 additions and 13 deletions

View File

@@ -116,13 +116,19 @@ public interface WebSession {
Mono<Void> invalidate();
/**
* Save the session persisting attributes (e.g. if stored remotely) and also
* sending the session id to the client if the session is new.
* <p>Note that a session must be started explicitly via {@link #start()} or
* implicitly by adding attributes or otherwise this method has no effect.
* Save the session through the {@code WebSessionStore} as follows:
* <ul>
* <li>If the session is new (i.e. created but never persisted), it must have
* been started explicitly via {@link #start()} or implicitly by adding
* attributes, or otherwise this method should have no effect.
* <li>If the session was retrieved through the {@code WebSessionStore},
* the implementation for this method must check whether the session was
* {@link #invalidate() invalidated} and if so return an error.
* </ul>
* <p>Note that this method is not intended for direct use by applications.
* Instead it is automatically invoked just before the response is
* committed is committed.
* @return {@code Mono} to indicate completion with success or error
* <p>Typically this method should be automatically invoked just before the
* response is committed so applications don't have to by default.
*/
Mono<Void> save();

View File

@@ -240,19 +240,37 @@ public class InMemoryWebSessionStore implements WebSessionStore {
@Override
public Mono<Void> save() {
if (sessions.size() >= maxSessions) {
expiredSessionChecker.removeExpiredSessions(clock.instant());
if (sessions.size() >= maxSessions) {
return Mono.error(new IllegalStateException("Max sessions limit reached: " + sessions.size()));
}
}
checkMaxSessionsLimit();
// Implicitly started session..
if (!getAttributes().isEmpty()) {
this.state.compareAndSet(State.NEW, State.STARTED);
}
InMemoryWebSessionStore.this.sessions.put(this.getId(), this);
if (isStarted()) {
// Save
InMemoryWebSessionStore.this.sessions.put(this.getId(), this);
// Unless it was invalidated
if (this.state.get().equals(State.EXPIRED)) {
InMemoryWebSessionStore.this.sessions.remove(this.getId());
return Mono.error(new IllegalStateException("Session was invalidated"));
}
}
return Mono.empty();
}
private void checkMaxSessionsLimit() {
if (sessions.size() >= maxSessions) {
expiredSessionChecker.removeExpiredSessions(clock.instant());
if (sessions.size() >= maxSessions) {
throw new IllegalStateException("Max sessions limit reached: " + sessions.size());
}
}
}
@Override
public boolean isExpired() {
return isExpired(clock.instant());