Description
Describe the bug
We are using the spring-session library with the Redis repository. I observed that an additional HGETALL call is being made to Redis. Removing this additional call in an environment with a high user base and high TPS would be beneficial.
To Reproduce
Any HTTP request that updates existing session results in the below list of calls to Redis
Pre-processing - load session from the repository
HGETALL
Post-processing - update session state in the repository
EXISTS
HMSET
PEXPIREAT
HGETALL - additional call that can be avoided
Expected behavior
Session loaded only once from the repository per request
Possible solution
Current implementation of SessionRepositoryRequestWrapper.commitSession() method:
private void commitSession() {
HttpSessionWrapper wrappedSession = getCurrentSession();
if (wrappedSession == null) {
if (isInvalidateClientSession()) {
SessionRepositoryFilter.this.httpSessionIdResolver.expireSession(this, this.response);
}
}
else {
S session = wrappedSession.getSession();
clearRequestedSessionCache();
SessionRepositoryFilter.this.sessionRepository.save(session);
String sessionId = session.getId();
if (!isRequestedSessionIdValid() || !sessionId.equals(getRequestedSessionId())) {
SessionRepositoryFilter.this.httpSessionIdResolver.setSessionId(this, this.response, sessionId);
}
}
}
clearRequestedSessionCache()
- clears session details cached locally
getRequestedSessionId()
- loads session from repository again
Moving clearRequestSessionCache()
call to the end as shown below would prevent the additional call
private void commitSession() {
HttpSessionWrapper wrappedSession = getCurrentSession();
if (wrappedSession == null) {
if (isInvalidateClientSession()) {
SessionRepositoryFilter.this.httpSessionIdResolver.expireSession(this, this.response);
}
}
else {
S session = wrappedSession.getSession();
SessionRepositoryFilter.this.sessionRepository.save(session);
String sessionId = session.getId();
if (!isRequestedSessionIdValid() || !sessionId.equals(getRequestedSessionId())) {
SessionRepositoryFilter.this.httpSessionIdResolver.setSessionId(this, this.response, sessionId);
}
clearRequestedSessionCache();
}
}
I am not sure whether the proposed change would have any side effects. Could someone please check and let me know?