@@ -45,7 +45,7 @@ public class InMemoryWebSessionStore implements WebSessionStore {
45
45
46
46
private Clock clock = Clock .system (ZoneId .of ("GMT" ));
47
47
48
- private final Map <String , WebSession > sessions = new ConcurrentHashMap <>();
48
+ private final Map <String , InMemoryWebSession > sessions = new ConcurrentHashMap <>();
49
49
50
50
51
51
/**
@@ -77,7 +77,7 @@ public Mono<WebSession> createWebSession() {
77
77
78
78
@ Override
79
79
public Mono <WebSession > retrieveSession (String id ) {
80
- WebSession session = this .sessions .get (id );
80
+ InMemoryWebSession session = this .sessions .get (id );
81
81
if (session == null ) {
82
82
return Mono .empty ();
83
83
}
@@ -86,6 +86,7 @@ else if (session.isExpired()) {
86
86
return Mono .empty ();
87
87
}
88
88
else {
89
+ session .updateLastAccessTime ();
89
90
return Mono .just (session );
90
91
}
91
92
}
@@ -98,27 +99,14 @@ public Mono<Void> removeSession(String id) {
98
99
99
100
public Mono <WebSession > updateLastAccessTime (WebSession webSession ) {
100
101
return Mono .fromSupplier (() -> {
102
+ Assert .isInstanceOf (InMemoryWebSession .class , webSession );
101
103
InMemoryWebSession session = (InMemoryWebSession ) webSession ;
102
- Instant lastAccessTime = Instant . now ( getClock () );
103
- return new InMemoryWebSession ( session , lastAccessTime ) ;
104
+ session . updateLastAccessTime ( );
105
+ return session ;
104
106
});
105
107
}
106
108
107
109
108
- // Private methods for InMemoryWebSession
109
-
110
- private Mono <Void > changeSessionId (String oldId , WebSession session ) {
111
- this .sessions .remove (oldId );
112
- this .sessions .put (session .getId (), session );
113
- return Mono .empty ();
114
- }
115
-
116
- private Mono <Void > storeSession (WebSession session ) {
117
- this .sessions .put (session .getId (), session );
118
- return Mono .empty ();
119
- }
120
-
121
-
122
110
private class InMemoryWebSession implements WebSession {
123
111
124
112
private final AtomicReference <String > id ;
@@ -127,12 +115,13 @@ private class InMemoryWebSession implements WebSession {
127
115
128
116
private final Instant creationTime ;
129
117
130
- private final Instant lastAccessTime ;
118
+ private volatile Instant lastAccessTime ;
131
119
132
120
private volatile Duration maxIdleTime ;
133
121
134
122
private volatile boolean started ;
135
123
124
+
136
125
InMemoryWebSession () {
137
126
this .id = new AtomicReference <>(String .valueOf (idGenerator .generateId ()));
138
127
this .attributes = new ConcurrentHashMap <>();
@@ -141,14 +130,6 @@ private class InMemoryWebSession implements WebSession {
141
130
this .maxIdleTime = Duration .ofMinutes (30 );
142
131
}
143
132
144
- InMemoryWebSession (InMemoryWebSession existingSession , Instant lastAccessTime ) {
145
- this .id = existingSession .id ;
146
- this .attributes = existingSession .attributes ;
147
- this .creationTime = existingSession .creationTime ;
148
- this .lastAccessTime = lastAccessTime ;
149
- this .maxIdleTime = existingSession .maxIdleTime ;
150
- this .started = existingSession .isStarted (); // Use method (explicit or implicit start)
151
- }
152
133
153
134
@ Override
154
135
public String getId () {
@@ -192,22 +173,33 @@ public boolean isStarted() {
192
173
193
174
@ Override
194
175
public Mono <Void > changeSessionId () {
195
- String oldId = this .id .get ();
176
+ String currentId = this .id .get ();
177
+ if (InMemoryWebSessionStore .this .sessions .remove (currentId ) == null ) {
178
+ return Mono .error (new IllegalStateException (
179
+ "Failed to change session id: " + currentId +
180
+ " because the Session is no longer present in the store." ));
181
+ }
196
182
String newId = String .valueOf (idGenerator .generateId ());
197
183
this .id .set (newId );
198
- return InMemoryWebSessionStore .this .changeSessionId (oldId , this ).doOnError (ex -> this .id .set (oldId ));
184
+ InMemoryWebSessionStore .this .sessions .put (this .getId (), this );
185
+ return Mono .empty ();
199
186
}
200
187
201
188
@ Override
202
189
public Mono <Void > save () {
203
- return InMemoryWebSessionStore .this .storeSession (this );
190
+ InMemoryWebSessionStore .this .sessions .put (this .getId (), this );
191
+ return Mono .empty ();
204
192
}
205
193
206
194
@ Override
207
195
public boolean isExpired () {
208
196
return (isStarted () && !this .maxIdleTime .isNegative () &&
209
197
Instant .now (getClock ()).minus (this .maxIdleTime ).isAfter (this .lastAccessTime ));
210
198
}
199
+
200
+ private void updateLastAccessTime () {
201
+ this .lastAccessTime = Instant .now (getClock ());
202
+ }
211
203
}
212
204
213
205
}
0 commit comments