Fixed - multiple Tomcat requests share different instances stored in the same session in readMode=REDIS #2476

pull/3048/head
Nikita Koksharov 4 years ago
parent be4f10218f
commit b50bfcc574

@ -29,6 +29,7 @@ import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Redisson Session object for Apache Tomcat * Redisson Session object for Apache Tomcat
@ -64,8 +65,9 @@ public class RedissonSession extends StandardSession {
private final ReadMode readMode; private final ReadMode readMode;
private final UpdateMode updateMode; private final UpdateMode updateMode;
private final AtomicInteger usages = new AtomicInteger();
private Map<String, Object> loadedAttributes = Collections.emptyMap();
private Set<String> removedAttributes = Collections.emptySet(); private Set<String> removedAttributes = Collections.emptySet();
private Set<String> updatedAttributes = Collections.emptySet();
private final boolean broadcastSessionEvents; private final boolean broadcastSessionEvents;
@ -79,7 +81,9 @@ public class RedissonSession extends StandardSession {
if (updateMode == UpdateMode.AFTER_REQUEST) { if (updateMode == UpdateMode.AFTER_REQUEST) {
removedAttributes = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); removedAttributes = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
updatedAttributes = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); }
if (readMode == ReadMode.REDIS) {
loadedAttributes = new ConcurrentHashMap<>();
} }
try { try {
@ -103,12 +107,19 @@ public class RedissonSession extends StandardSession {
return null; return null;
} }
if (updatedAttributes.contains(name) if (removedAttributes.contains(name)) {
|| removedAttributes.contains(name)) {
return super.getAttribute(name); return super.getAttribute(name);
} }
return map.get(name); Object value = loadedAttributes.get(name);
if (value == null) {
value = map.get(name);
if (value != null) {
loadedAttributes.put(name, value);
}
}
return value;
} else { } else {
if (!loaded) { if (!loaded) {
synchronized (this) { synchronized (this) {
@ -170,6 +181,7 @@ public class RedissonSession extends StandardSession {
topic.publish(new AttributesClearMessage(redissonManager.getNodeId(), getId())); topic.publish(new AttributesClearMessage(redissonManager.getNodeId(), getId()));
} }
map = null; map = null;
loadedAttributes.clear();
} }
@Override @Override
@ -310,9 +322,11 @@ public class RedissonSession extends StandardSession {
if (updateMode == UpdateMode.DEFAULT && map != null) { if (updateMode == UpdateMode.DEFAULT && map != null) {
fastPut(name, value); fastPut(name, value);
} }
if (readMode == ReadMode.REDIS) {
loadedAttributes.put(name, value);
}
if (updateMode == UpdateMode.AFTER_REQUEST) { if (updateMode == UpdateMode.AFTER_REQUEST) {
removedAttributes.remove(name); removedAttributes.remove(name);
updatedAttributes.add(name);
} }
} }
@ -330,9 +344,11 @@ public class RedissonSession extends StandardSession {
topic.publish(new AttributeRemoveMessage(redissonManager.getNodeId(), getId(), new HashSet<String>(Arrays.asList(name)))); topic.publish(new AttributeRemoveMessage(redissonManager.getNodeId(), getId(), new HashSet<String>(Arrays.asList(name))));
} }
} }
if (readMode == ReadMode.REDIS) {
loadedAttributes.remove(name);
}
if (updateMode == UpdateMode.AFTER_REQUEST) { if (updateMode == UpdateMode.AFTER_REQUEST) {
removedAttributes.add(name); removedAttributes.add(name);
updatedAttributes.remove(name);
} }
} }
@ -377,8 +393,8 @@ public class RedissonSession extends StandardSession {
} }
} }
updatedAttributes.clear();
removedAttributes.clear(); removedAttributes.clear();
loadedAttributes.clear();
expireSession(); expireSession();
} }
@ -430,6 +446,16 @@ public class RedissonSession extends StandardSession {
public void recycle() { public void recycle() {
super.recycle(); super.recycle();
map = null; map = null;
loadedAttributes.clear();
}
public void startUsage() {
usages.incrementAndGet();
}
public void endUsage() {
if (usages.decrementAndGet() == 0) {
loadedAttributes.clear();
}
} }
} }

@ -17,28 +17,19 @@ package org.redisson.tomcat;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.apache.catalina.Context; import org.apache.catalina.*;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.Pipeline;
import org.apache.catalina.Session;
import org.apache.catalina.SessionEvent;
import org.apache.catalina.SessionListener;
import org.apache.catalina.session.ManagerBase; import org.apache.catalina.session.ManagerBase;
import org.apache.catalina.valves.ValveBase;
import org.apache.juli.logging.Log; import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory; import org.apache.juli.logging.LogFactory;
import org.redisson.Redisson; import org.redisson.Redisson;
import org.redisson.api.RMap;
import org.redisson.api.RSet; import org.redisson.api.RSet;
import org.redisson.api.RMap;
import org.redisson.api.RTopic; import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
import org.redisson.api.listener.MessageListener; import org.redisson.api.listener.MessageListener;
@ -71,7 +62,7 @@ public class RedissonSessionManager extends ManagerBase {
private final String nodeId = UUID.randomUUID().toString(); private final String nodeId = UUID.randomUUID().toString();
private static UpdateValve updateValve; private static ValveBase updateValve;
private static Set<String> contextInUse = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); private static Set<String> contextInUse = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
@ -151,7 +142,7 @@ public class RedissonSessionManager extends ManagerBase {
} }
return session; return session;
} }
public RSet<String> getNotifiedNodes(String sessionId) { public RSet<String> getNotifiedNodes(String sessionId) {
String separator = keyPrefix == null || keyPrefix.isEmpty() ? "" : ":"; String separator = keyPrefix == null || keyPrefix.isEmpty() ? "" : ":";
String name = keyPrefix + separator + "redisson:tomcat_notified_nodes:" + sessionId; String name = keyPrefix + separator + "redisson:tomcat_notified_nodes:" + sessionId;
@ -186,7 +177,7 @@ public class RedissonSessionManager extends ManagerBase {
log.error("Can't read session object by id: " + id, e); log.error("Can't read session object by id: " + id, e);
} }
if (attrs.isEmpty() || (broadcastSessionEvents && getNotifiedNodes(id).contains(nodeId))) { if (attrs.isEmpty() || (broadcastSessionEvents && getNotifiedNodes(id).contains(nodeId))) {
log.info("Session " + id + " can't be found"); log.info("Session " + id + " can't be found");
return null; return null;
} }
@ -207,7 +198,6 @@ public class RedissonSessionManager extends ManagerBase {
return result; return result;
} }
@Override @Override
public Session createEmptySession() { public Session createEmptySession() {
@ -219,7 +209,7 @@ public class RedissonSessionManager extends ManagerBase {
super.add(session); super.add(session);
((RedissonSession)session).save(); ((RedissonSession)session).save();
} }
@Override @Override
public void remove(Session session, boolean update) { public void remove(Session session, boolean update) {
super.remove(session, update); super.remove(session, update);
@ -228,7 +218,7 @@ public class RedissonSessionManager extends ManagerBase {
((RedissonSession)session).delete(); ((RedissonSession)session).delete();
} }
} }
public RedissonClient getRedisson() { public RedissonClient getRedisson() {
return redisson; return redisson;
} }
@ -264,6 +254,11 @@ public class RedissonSessionManager extends ManagerBase {
updateValve = new UpdateValve(); updateValve = new UpdateValve();
pipeline.addValve(updateValve); pipeline.addValve(updateValve);
} }
} else if (readMode == ReadMode.REDIS) {
if (updateValve == null) {
updateValve = new UsageValve();
pipeline.addValve(updateValve);
}
} }
} }

@ -0,0 +1,71 @@
/**
* Copyright (c) 2013-2020 Nikita Koksharov
*
* 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.redisson.tomcat;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* Redisson Valve object for Apache Tomcat
*
* @author Nikita Koksharov
*
*/
public class UsageValve extends ValveBase {
private static final String ALREADY_FILTERED_NOTE = UsageValve.class.getName() + ".ALREADY_FILTERED_NOTE";
public UsageValve() {
super(true);
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
if (getNext() == null) {
return;
}
//check if we already filtered/processed this request
if (request.getNote(ALREADY_FILTERED_NOTE) == null) {
request.setNote(ALREADY_FILTERED_NOTE, Boolean.TRUE);
RedissonSession s = null;
try {
HttpSession session = request.getSession(false);
if (session != null) {
s = (RedissonSession) request.getContext().getManager().findSession(session.getId());
if (s != null) {
s.startUsage();
}
}
getNext().invoke(request, response);
} finally {
request.removeNote(ALREADY_FILTERED_NOTE);
if (s != null) {
s.endUsage();
}
}
} else {
getNext().invoke(request, response);
}
}
}

@ -29,6 +29,7 @@ import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Redisson Session object for Apache Tomcat * Redisson Session object for Apache Tomcat
@ -64,8 +65,9 @@ public class RedissonSession extends StandardSession {
private final ReadMode readMode; private final ReadMode readMode;
private final UpdateMode updateMode; private final UpdateMode updateMode;
private final AtomicInteger usages = new AtomicInteger();
private Map<String, Object> loadedAttributes = Collections.emptyMap();
private Set<String> removedAttributes = Collections.emptySet(); private Set<String> removedAttributes = Collections.emptySet();
private Set<String> updatedAttributes = Collections.emptySet();
private final boolean broadcastSessionEvents; private final boolean broadcastSessionEvents;
@ -79,7 +81,9 @@ public class RedissonSession extends StandardSession {
if (updateMode == UpdateMode.AFTER_REQUEST) { if (updateMode == UpdateMode.AFTER_REQUEST) {
removedAttributes = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); removedAttributes = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
updatedAttributes = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); }
if (readMode == ReadMode.REDIS) {
loadedAttributes = new ConcurrentHashMap<>();
} }
try { try {
@ -103,12 +107,19 @@ public class RedissonSession extends StandardSession {
return null; return null;
} }
if (updatedAttributes.contains(name) if (removedAttributes.contains(name)) {
|| removedAttributes.contains(name)) {
return super.getAttribute(name); return super.getAttribute(name);
} }
return map.get(name); Object value = loadedAttributes.get(name);
if (value == null) {
value = map.get(name);
if (value != null) {
loadedAttributes.put(name, value);
}
}
return value;
} else { } else {
if (!loaded) { if (!loaded) {
synchronized (this) { synchronized (this) {
@ -170,6 +181,7 @@ public class RedissonSession extends StandardSession {
topic.publish(new AttributesClearMessage(redissonManager.getNodeId(), getId())); topic.publish(new AttributesClearMessage(redissonManager.getNodeId(), getId()));
} }
map = null; map = null;
loadedAttributes.clear();
} }
@Override @Override
@ -310,9 +322,11 @@ public class RedissonSession extends StandardSession {
if (updateMode == UpdateMode.DEFAULT && map != null) { if (updateMode == UpdateMode.DEFAULT && map != null) {
fastPut(name, value); fastPut(name, value);
} }
if (readMode == ReadMode.REDIS) {
loadedAttributes.put(name, value);
}
if (updateMode == UpdateMode.AFTER_REQUEST) { if (updateMode == UpdateMode.AFTER_REQUEST) {
removedAttributes.remove(name); removedAttributes.remove(name);
updatedAttributes.add(name);
} }
} }
@ -330,9 +344,11 @@ public class RedissonSession extends StandardSession {
topic.publish(new AttributeRemoveMessage(redissonManager.getNodeId(), getId(), new HashSet<String>(Arrays.asList(name)))); topic.publish(new AttributeRemoveMessage(redissonManager.getNodeId(), getId(), new HashSet<String>(Arrays.asList(name))));
} }
} }
if (readMode == ReadMode.REDIS) {
loadedAttributes.remove(name);
}
if (updateMode == UpdateMode.AFTER_REQUEST) { if (updateMode == UpdateMode.AFTER_REQUEST) {
removedAttributes.add(name); removedAttributes.add(name);
updatedAttributes.remove(name);
} }
} }
@ -377,8 +393,8 @@ public class RedissonSession extends StandardSession {
} }
} }
updatedAttributes.clear();
removedAttributes.clear(); removedAttributes.clear();
loadedAttributes.clear();
expireSession(); expireSession();
} }
@ -430,6 +446,16 @@ public class RedissonSession extends StandardSession {
public void recycle() { public void recycle() {
super.recycle(); super.recycle();
map = null; map = null;
loadedAttributes.clear();
}
public void startUsage() {
usages.incrementAndGet();
}
public void endUsage() {
if (usages.decrementAndGet() == 0) {
loadedAttributes.clear();
}
} }
} }

@ -17,11 +17,7 @@ package org.redisson.tomcat;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
@ -33,6 +29,7 @@ import org.apache.catalina.Session;
import org.apache.catalina.SessionEvent; import org.apache.catalina.SessionEvent;
import org.apache.catalina.SessionListener; import org.apache.catalina.SessionListener;
import org.apache.catalina.session.ManagerBase; import org.apache.catalina.session.ManagerBase;
import org.apache.catalina.valves.ValveBase;
import org.apache.juli.logging.Log; import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory; import org.apache.juli.logging.LogFactory;
import org.redisson.Redisson; import org.redisson.Redisson;
@ -70,7 +67,7 @@ public class RedissonSessionManager extends ManagerBase {
private final String nodeId = UUID.randomUUID().toString(); private final String nodeId = UUID.randomUUID().toString();
private static UpdateValve updateValve; private static ValveBase updateValve;
private static Set<String> contextInUse = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); private static Set<String> contextInUse = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
@ -262,6 +259,11 @@ public class RedissonSessionManager extends ManagerBase {
updateValve = new UpdateValve(); updateValve = new UpdateValve();
pipeline.addValve(updateValve); pipeline.addValve(updateValve);
} }
} else if (readMode == ReadMode.REDIS) {
if (updateValve == null) {
updateValve = new UsageValve();
pipeline.addValve(updateValve);
}
} }
} }

@ -0,0 +1,71 @@
/**
* Copyright (c) 2013-2020 Nikita Koksharov
*
* 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.redisson.tomcat;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* Redisson Valve object for Apache Tomcat
*
* @author Nikita Koksharov
*
*/
public class UsageValve extends ValveBase {
private static final String ALREADY_FILTERED_NOTE = UsageValve.class.getName() + ".ALREADY_FILTERED_NOTE";
public UsageValve() {
super(true);
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
if (getNext() == null) {
return;
}
//check if we already filtered/processed this request
if (request.getNote(ALREADY_FILTERED_NOTE) == null) {
request.setNote(ALREADY_FILTERED_NOTE, Boolean.TRUE);
RedissonSession s = null;
try {
HttpSession session = request.getSession(false);
if (session != null) {
s = (RedissonSession) request.getContext().getManager().findSession(session.getId());
if (s != null) {
s.startUsage();
}
}
getNext().invoke(request, response);
} finally {
request.removeNote(ALREADY_FILTERED_NOTE);
if (s != null) {
s.endUsage();
}
}
} else {
getNext().invoke(request, response);
}
}
}

@ -29,6 +29,7 @@ import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Redisson Session object for Apache Tomcat * Redisson Session object for Apache Tomcat
@ -64,8 +65,9 @@ public class RedissonSession extends StandardSession {
private final ReadMode readMode; private final ReadMode readMode;
private final UpdateMode updateMode; private final UpdateMode updateMode;
private final AtomicInteger usages = new AtomicInteger();
private Map<String, Object> loadedAttributes = Collections.emptyMap();
private Set<String> removedAttributes = Collections.emptySet(); private Set<String> removedAttributes = Collections.emptySet();
private Set<String> updatedAttributes = Collections.emptySet();
private final boolean broadcastSessionEvents; private final boolean broadcastSessionEvents;
@ -79,7 +81,9 @@ public class RedissonSession extends StandardSession {
if (updateMode == UpdateMode.AFTER_REQUEST) { if (updateMode == UpdateMode.AFTER_REQUEST) {
removedAttributes = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); removedAttributes = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
updatedAttributes = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); }
if (readMode == ReadMode.REDIS) {
loadedAttributes = new ConcurrentHashMap<>();
} }
try { try {
@ -103,12 +107,19 @@ public class RedissonSession extends StandardSession {
return null; return null;
} }
if (updatedAttributes.contains(name) if (removedAttributes.contains(name)) {
|| removedAttributes.contains(name)) {
return super.getAttribute(name); return super.getAttribute(name);
} }
return map.get(name); Object value = loadedAttributes.get(name);
if (value == null) {
value = map.get(name);
if (value != null) {
loadedAttributes.put(name, value);
}
}
return value;
} else { } else {
if (!loaded) { if (!loaded) {
synchronized (this) { synchronized (this) {
@ -170,6 +181,7 @@ public class RedissonSession extends StandardSession {
topic.publish(new AttributesClearMessage(redissonManager.getNodeId(), getId())); topic.publish(new AttributesClearMessage(redissonManager.getNodeId(), getId()));
} }
map = null; map = null;
loadedAttributes.clear();
} }
@Override @Override
@ -310,9 +322,11 @@ public class RedissonSession extends StandardSession {
if (updateMode == UpdateMode.DEFAULT && map != null) { if (updateMode == UpdateMode.DEFAULT && map != null) {
fastPut(name, value); fastPut(name, value);
} }
if (readMode == ReadMode.REDIS) {
loadedAttributes.put(name, value);
}
if (updateMode == UpdateMode.AFTER_REQUEST) { if (updateMode == UpdateMode.AFTER_REQUEST) {
removedAttributes.remove(name); removedAttributes.remove(name);
updatedAttributes.add(name);
} }
} }
@ -330,9 +344,11 @@ public class RedissonSession extends StandardSession {
topic.publish(new AttributeRemoveMessage(redissonManager.getNodeId(), getId(), new HashSet<String>(Arrays.asList(name)))); topic.publish(new AttributeRemoveMessage(redissonManager.getNodeId(), getId(), new HashSet<String>(Arrays.asList(name))));
} }
} }
if (readMode == ReadMode.REDIS) {
loadedAttributes.remove(name);
}
if (updateMode == UpdateMode.AFTER_REQUEST) { if (updateMode == UpdateMode.AFTER_REQUEST) {
removedAttributes.add(name); removedAttributes.add(name);
updatedAttributes.remove(name);
} }
} }
@ -377,8 +393,8 @@ public class RedissonSession extends StandardSession {
} }
} }
updatedAttributes.clear();
removedAttributes.clear(); removedAttributes.clear();
loadedAttributes.clear();
expireSession(); expireSession();
} }
@ -430,6 +446,16 @@ public class RedissonSession extends StandardSession {
public void recycle() { public void recycle() {
super.recycle(); super.recycle();
map = null; map = null;
loadedAttributes.clear();
}
public void startUsage() {
usages.incrementAndGet();
}
public void endUsage() {
if (usages.decrementAndGet() == 0) {
loadedAttributes.clear();
}
} }
} }

@ -17,11 +17,7 @@ package org.redisson.tomcat;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
@ -33,6 +29,7 @@ import org.apache.catalina.Session;
import org.apache.catalina.SessionEvent; import org.apache.catalina.SessionEvent;
import org.apache.catalina.SessionListener; import org.apache.catalina.SessionListener;
import org.apache.catalina.session.ManagerBase; import org.apache.catalina.session.ManagerBase;
import org.apache.catalina.valves.ValveBase;
import org.apache.juli.logging.Log; import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory; import org.apache.juli.logging.LogFactory;
import org.redisson.Redisson; import org.redisson.Redisson;
@ -70,7 +67,7 @@ public class RedissonSessionManager extends ManagerBase {
private final String nodeId = UUID.randomUUID().toString(); private final String nodeId = UUID.randomUUID().toString();
private static UpdateValve updateValve; private static ValveBase updateValve;
private static Set<String> contextInUse = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>()); private static Set<String> contextInUse = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
@ -262,6 +259,11 @@ public class RedissonSessionManager extends ManagerBase {
updateValve = new UpdateValve(); updateValve = new UpdateValve();
pipeline.addValve(updateValve); pipeline.addValve(updateValve);
} }
} else if (readMode == ReadMode.REDIS) {
if (updateValve == null) {
updateValve = new UsageValve();
pipeline.addValve(updateValve);
}
} }
} }

@ -0,0 +1,71 @@
/**
* Copyright (c) 2013-2020 Nikita Koksharov
*
* 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.redisson.tomcat;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* Redisson Valve object for Apache Tomcat
*
* @author Nikita Koksharov
*
*/
public class UsageValve extends ValveBase {
private static final String ALREADY_FILTERED_NOTE = UsageValve.class.getName() + ".ALREADY_FILTERED_NOTE";
public UsageValve() {
super(true);
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
if (getNext() == null) {
return;
}
//check if we already filtered/processed this request
if (request.getNote(ALREADY_FILTERED_NOTE) == null) {
request.setNote(ALREADY_FILTERED_NOTE, Boolean.TRUE);
RedissonSession s = null;
try {
HttpSession session = request.getSession(false);
if (session != null) {
s = (RedissonSession) request.getContext().getManager().findSession(session.getId());
if (s != null) {
s.startUsage();
}
}
getNext().invoke(request, response);
} finally {
request.removeNote(ALREADY_FILTERED_NOTE);
if (s != null) {
s.endUsage();
}
}
} else {
getNext().invoke(request, response);
}
}
}
Loading…
Cancel
Save