Skip to content

SessionRepositoryFilter's getRequestedSession is called unnecessarily. #1424

Open
@hosoitk

Description

@hosoitk

When Spring Session used in the application was upgraded from 1.3.1.RELEASE to 2.1.3.RELEASE, performance was verified and it was confirmed that the CPU utilization has increased by about 10%.
When profiling was performed using the function -agentlib: hprof = cpu = samples, it was confirmed that the execution time of RedisOperationsSessionRepository.getSession (String, boolean) has increased after version upgrade.

The increase in the number of executions of RedisOperationsSessionRepository.getSession (String, boolean) is due to the following two updates.

Update point 1

After Spring Session 1.3.4.RELEASE, with implementation of SessionCommittingRequestDispatcher which introduced the change that when screen transition is made to a JSP page containing jsp: include, commitSession is executed each time jsp: include is executed.

Update point 2

getRequestedSessionId has been modified since Spring Session 2.0.0.RELEASE, getRequestedSessionId has been changed to check whether the session ID obtained from cookie by RedisOperationsSessionRepository.findById exists in the session.

commitSession calls getRequestedSessionId, getRequestedSessionId calls RedisOperationsSessionRepository.findById via getRequestedSession.
Because RedisOperationsSessionRepository.findById has become is a process that calls RedisOperationsSessionRepository.getSession(String, boolean), increase in the number of executions of commitSession leads to an increase of RedisOperationsSessionRepository.getSession (String, boolean)

This is getRequestedSessionId but due to the modification from Spring Session 2.1.1.RELEASE onwards, getRequestedSession can be executed to update requestedSessionId only when requestedSessionId is null, by caching the requestedSessionId.

However, at the same time in clearRequestedSessionCache a process is added to assign null to requestedSessionId as well and in commitSession in order to execute clearRequestedSessionCache before executing requestedSessionId it has become necessary to execute getRequestedSession.

@Override
public String getRequestedSessionId() {
if (this.requestedSessionId == null) {
getRequestedSession();
}
return this.requestedSessionId;
}

private void clearRequestedSessionCache() {
this.requestedSessionCached = false;
this.requestedSession = null;
this.requestedSessionId = null;
}

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);
}
}
}

Since requestedSessionId is not changed during the request, it is better not to clear it

If the call of getRequestedSession is properly controlled from getRequestedSessionId, even if getRequestedSessionId is called from commitSession by SessionCommittingRequestDispatcher.include (ServletRequest, ServletResponse) the behavior of executing RedisOperationsSessionRepository.findById every time will not occur . It is likely that the number of RedisOperationsSessionRepository.getSession (String, boolean) execution will be the same as before the version upgrade.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions