Skip to content

SessionRepositoryFilter - session loaded an additional time from repository due to premature local state reset #2131

Closed as not planned
@sudhirtumati

Description

@sudhirtumati

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions