Add RedisFlushMode
This commit allows Redis support to flush lazily (already supported) or immediately (new). Fixes gh-273
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.session.data.redis;
|
||||
|
||||
import org.springframework.session.SessionRepository;
|
||||
|
||||
/**
|
||||
* Specifies when to write to the backing Redis instance.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 1.1
|
||||
*/
|
||||
public enum RedisFlushMode {
|
||||
/**
|
||||
* Only writes to Redis when
|
||||
* {@link SessionRepository#save(org.springframework.session.Session)} is
|
||||
* invoked. In a web environment this is typically done as soon as the HTTP
|
||||
* response is committed.
|
||||
*/
|
||||
ON_SAVE,
|
||||
|
||||
/**
|
||||
* Writes to Redis as soon as possible. For example
|
||||
* {@link SessionRepository#createSession()} will write the session to
|
||||
* Redis. Another example is that setting an attribute on the session will
|
||||
* also write to Redis immediately.
|
||||
*/
|
||||
IMMEDIATE
|
||||
}
|
||||
@@ -304,6 +304,8 @@ public class RedisOperationsSessionRepository implements FindByIndexNameSessionR
|
||||
|
||||
private RedisSerializer<Object> defaultSerializer = new JdkSerializationRedisSerializer();
|
||||
|
||||
private RedisFlushMode redisFlushMode = RedisFlushMode.ON_SAVE;
|
||||
|
||||
/**
|
||||
* Allows creating an instance and uses a default {@link RedisOperations} for both managing the session and the expirations.
|
||||
*
|
||||
@@ -360,6 +362,14 @@ public class RedisOperationsSessionRepository implements FindByIndexNameSessionR
|
||||
this.defaultSerializer = defaultSerializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redisFlushMode
|
||||
*/
|
||||
public void setRedisFlushMode(RedisFlushMode redisFlushMode) {
|
||||
Assert.notNull(redisFlushMode, "redisFlushMode cannot be null");
|
||||
this.redisFlushMode = redisFlushMode;
|
||||
}
|
||||
|
||||
public void save(RedisSession session) {
|
||||
session.saveDelta();
|
||||
if(session.isNew()) {
|
||||
@@ -636,6 +646,7 @@ public class RedisOperationsSessionRepository implements FindByIndexNameSessionR
|
||||
delta.put(MAX_INACTIVE_ATTR, getMaxInactiveIntervalInSeconds());
|
||||
delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime());
|
||||
this.isNew = true;
|
||||
flushImmediateIfNecessary();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -656,6 +667,7 @@ public class RedisOperationsSessionRepository implements FindByIndexNameSessionR
|
||||
public void setLastAccessedTime(long lastAccessedTime) {
|
||||
cached.setLastAccessedTime(lastAccessedTime);
|
||||
delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime());
|
||||
flushImmediateIfNecessary();
|
||||
}
|
||||
|
||||
public boolean isExpired() {
|
||||
@@ -681,6 +693,7 @@ public class RedisOperationsSessionRepository implements FindByIndexNameSessionR
|
||||
public void setMaxInactiveIntervalInSeconds(int interval) {
|
||||
cached.setMaxInactiveIntervalInSeconds(interval);
|
||||
delta.put(MAX_INACTIVE_ATTR, getMaxInactiveIntervalInSeconds());
|
||||
flushImmediateIfNecessary();
|
||||
}
|
||||
|
||||
public int getMaxInactiveIntervalInSeconds() {
|
||||
@@ -699,11 +712,19 @@ public class RedisOperationsSessionRepository implements FindByIndexNameSessionR
|
||||
public void setAttribute(String attributeName, Object attributeValue) {
|
||||
cached.setAttribute(attributeName, attributeValue);
|
||||
delta.put(getSessionAttrNameKey(attributeName), attributeValue);
|
||||
flushImmediateIfNecessary();
|
||||
}
|
||||
|
||||
public void removeAttribute(String attributeName) {
|
||||
cached.removeAttribute(attributeName);
|
||||
delta.put(getSessionAttrNameKey(attributeName), null);
|
||||
flushImmediateIfNecessary();
|
||||
}
|
||||
|
||||
private void flushImmediateIfNecessary() {
|
||||
if(redisFlushMode == RedisFlushMode.IMMEDIATE) {
|
||||
saveDelta();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,9 @@ import java.lang.annotation.Target;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
|
||||
import org.springframework.session.data.redis.RedisFlushMode;
|
||||
|
||||
/**
|
||||
* Add this annotation to an {@code @Configuration} class to expose the
|
||||
@@ -76,4 +78,22 @@ public @interface EnableRedisHttpSession {
|
||||
* @return the unique namespace for keys
|
||||
*/
|
||||
String redisNamespace() default "";
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets the flush mode for the Redis sessions. The default is IMMEDIATE
|
||||
* which only updates the backing Redis when
|
||||
* {@link SessionRepository#save(org.springframework.session.Session)} is
|
||||
* invoked. In a web environment this happens just before the HTTP resposne
|
||||
* is committed.
|
||||
* </p>
|
||||
* <p>
|
||||
* Setting the value to IMMEDIATE will ensure that the any updates to the
|
||||
* Session are immediately written to the Redis instance.
|
||||
* </p>
|
||||
*
|
||||
* @return the {@link RedisFlushMode} to use
|
||||
* @since 1.1
|
||||
*/
|
||||
RedisFlushMode redisFlushMode() default RedisFlushMode.ON_SAVE;
|
||||
}
|
||||
@@ -37,10 +37,12 @@ import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
|
||||
import org.springframework.session.data.redis.RedisFlushMode;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction;
|
||||
import org.springframework.session.data.redis.config.ConfigureRedisAction;
|
||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -63,6 +65,8 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
|
||||
private String redisNamespace = "";
|
||||
|
||||
private RedisFlushMode redisFlushMode = RedisFlushMode.ON_SAVE;
|
||||
|
||||
private RedisSerializer<Object> defaultRedisSerializer;
|
||||
|
||||
@Bean
|
||||
@@ -102,6 +106,8 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
if(StringUtils.hasText(redisNamespace)) {
|
||||
sessionRepository.setRedisKeyNamespace(redisNamespace);
|
||||
}
|
||||
|
||||
sessionRepository.setRedisFlushMode(redisFlushMode);
|
||||
return sessionRepository;
|
||||
}
|
||||
|
||||
@@ -113,6 +119,11 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
this.redisNamespace = namespace;
|
||||
}
|
||||
|
||||
public void setRedisFlushMode(RedisFlushMode redisFlushMode) {
|
||||
Assert.notNull(redisFlushMode, "redisFlushMode cannot be null");
|
||||
this.redisFlushMode = redisFlushMode;
|
||||
}
|
||||
|
||||
private String getRedisNamespace() {
|
||||
if(StringUtils.hasText(this.redisNamespace)) {
|
||||
return this.redisNamespace;
|
||||
@@ -126,6 +137,7 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
|
||||
maxInactiveIntervalInSeconds = enableAttrs.getNumber("maxInactiveIntervalInSeconds");
|
||||
this.redisNamespace = enableAttrs.getString("redisNamespace");
|
||||
this.redisFlushMode = enableAttrs.getEnum("redisFlushMode");
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
Reference in New Issue
Block a user