Skip to content

Commit

Permalink
refactor: indexed session repository
Browse files Browse the repository at this point in the history
  • Loading branch information
guqing committed Apr 22, 2024
1 parent 434a581 commit 8511d67
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public ReactiveIndexedSessionRepository<MapSession> reactiveSessionRepository(
ServerProperties serverProperties) {
var repository = new InMemoryReactiveIndexedSessionRepository(new ConcurrentHashMap<>());
var timeout = sessionProperties.determineTimeout(
() -> serverProperties.getServlet().getSession().getTimeout());
() -> serverProperties.getReactive().getSession().getTimeout());
repository.setDefaultMaxInactiveInterval(timeout);
return repository;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package run.halo.app.security.session;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.time.Duration;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -25,20 +28,36 @@ public class InMemoryReactiveIndexedSessionRepository extends ReactiveMapSession
private final ConcurrentMap<IndexKey, Set<String>> indexSessionIdMap =
new ConcurrentHashMap<>();

/**
* Prevent other requests from being parsed and acquiring the session during its deletion,
* which could result in an unintended renewal. Currently, it acts as a buffer, and having a
* slightly prolonged expiration period is sufficient.
*/
private final Cache<String, Boolean> invalidateSessionIds = CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofMinutes(10))
.maximumSize(10_000)
.build();

public InMemoryReactiveIndexedSessionRepository(Map<String, Session> sessions) {
super(sessions);
}

@Override
public Mono<Void> save(MapSession session) {
if (invalidateSessionIds.getIfPresent(session.getId()) != null) {
return this.deleteById(session.getId());
}
return super.save(session)
.then(updateIndex(session));
}

@Override
public Mono<Void> deleteById(String id) {
return super.deleteById(id)
.then(removeIndex(id));
return removeIndex(id)
.then(Mono.defer(() -> {
invalidateSessionIds.put(id, true);
return super.deleteById(id);
}));
}

@Override
Expand All @@ -47,6 +66,7 @@ public Mono<Map<String, MapSession>> findByIndexNameAndIndexValue(String indexNa
var indexKey = new IndexKey(indexName, indexValue);
return Flux.fromIterable(indexSessionIdMap.getOrDefault(indexKey, Set.of()))
.flatMap(this::findById)
.filter(session -> invalidateSessionIds.getIfPresent(session.getId()) == null)
.collectMap(Session::getId);
}

Expand All @@ -59,6 +79,7 @@ public Mono<Map<String, MapSession>> findByPrincipalName(String principalName) {
public void destroy() {
sessionIdIndexMap.clear();
indexSessionIdMap.clear();
invalidateSessionIds.invalidateAll();
}

Mono<Void> removeIndex(String sessionId) {
Expand Down

0 comments on commit 8511d67

Please sign in to comment.