diff --git a/tomcat-core/src/main/java/com/hazelcast/session/LocalSessionsInvalidateListener.java b/tomcat-core/src/main/java/com/hazelcast/session/LocalSessionsInvalidateListener.java new file mode 100644 index 0000000..eba129b --- /dev/null +++ b/tomcat-core/src/main/java/com/hazelcast/session/LocalSessionsInvalidateListener.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008-2019, Hazelcast, Inc. All Rights Reserved. + */ + +package com.hazelcast.session; + +import com.hazelcast.core.EntryEvent; +import com.hazelcast.map.listener.EntryEvictedListener; +import com.hazelcast.map.listener.EntryRemovedListener; +import org.apache.catalina.Session; + +import java.util.Map; + +public class LocalSessionsInvalidateListener implements EntryEvictedListener, + EntryRemovedListener { + + private Map sessions; + + public LocalSessionsInvalidateListener(Map sessions) { + this.sessions = sessions; + } + + @Override + public void entryEvicted(EntryEvent event) { + invalidateSessions(event); + } + + @Override + public void entryRemoved(EntryEvent event) { + invalidateSessions(event); + } + + private void invalidateSessions(EntryEvent entryEvent) { + if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) { + sessions.remove(entryEvent.getKey()); + } + } +} diff --git a/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index ff8086d..d427cdf 100644 --- a/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -4,11 +4,8 @@ package com.hazelcast.session; -import com.hazelcast.core.EntryEvent; -import com.hazelcast.core.EntryListener; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; -import com.hazelcast.core.MapEvent; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -124,29 +121,7 @@ public void start() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryListener() { - public void entryAdded(EntryEvent event) { - } - - public void entryRemoved(EntryEvent entryEvent) { - if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) { - sessions.remove(entryEvent.getKey()); - } - } - - public void entryUpdated(EntryEvent event) { - } - - public void entryEvicted(EntryEvent entryEvent) { - entryRemoved(entryEvent); - } - - public void mapEvicted(MapEvent event) { - } - - public void mapCleared(MapEvent event) { - } - }, false); + sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false); } log.info("HazelcastSessionManager started..."); @@ -238,8 +213,14 @@ public Session findSession(String id) throws IOException { sessions.put(id, hazelcastSession); // call remove method to trigger eviction Listener on each node to invalidate local sessions - sessionMap.remove(id); - sessionMap.set(id, hazelcastSession); + // the call are performed in a pessimistic lock block to prevent concurrency problems whilst finding sessions + sessionMap.lock(id); + try { + sessionMap.remove(id); + sessionMap.set(id, hazelcastSession); + } finally { + sessionMap.unlock(id); + } return hazelcastSession; diff --git a/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index 10c32af..ea33184 100644 --- a/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -4,11 +4,8 @@ package com.hazelcast.session; -import com.hazelcast.core.EntryEvent; -import com.hazelcast.core.EntryListener; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; -import com.hazelcast.core.MapEvent; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -111,29 +108,7 @@ public void startInternal() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryListener() { - public void entryAdded(EntryEvent event) { - } - - public void entryRemoved(EntryEvent entryEvent) { - if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) { - sessions.remove(entryEvent.getKey()); - } - } - - public void entryUpdated(EntryEvent event) { - } - - public void entryEvicted(EntryEvent entryEvent) { - entryRemoved(entryEvent); - } - - public void mapEvicted(MapEvent event) { - } - - public void mapCleared(MapEvent event) { - } - }, false); + sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false); } log.info("HazelcastSessionManager started..."); @@ -237,8 +212,14 @@ public Session findSession(String id) throws IOException { sessions.put(id, hazelcastSession); // call remove method to trigger eviction Listener on each node to invalidate local sessions - sessionMap.remove(id); - sessionMap.set(id, hazelcastSession); + // the call are performed in a pessimistic lock block to prevent concurrency problems whilst finding sessions + sessionMap.lock(id); + try { + sessionMap.remove(id); + sessionMap.set(id, hazelcastSession); + } finally { + sessionMap.unlock(id); + } return hazelcastSession; } else { diff --git a/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index 531298c..64715c2 100644 --- a/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -4,11 +4,8 @@ package com.hazelcast.session; -import com.hazelcast.core.EntryEvent; -import com.hazelcast.core.EntryListener; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; -import com.hazelcast.core.MapEvent; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -109,29 +106,7 @@ public void startInternal() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryListener() { - public void entryAdded(EntryEvent event) { - } - - public void entryRemoved(EntryEvent entryEvent) { - if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) { - sessions.remove(entryEvent.getKey()); - } - } - - public void entryUpdated(EntryEvent event) { - } - - public void entryEvicted(EntryEvent entryEvent) { - entryRemoved(entryEvent); - } - - public void mapEvicted(MapEvent event) { - } - - public void mapCleared(MapEvent event) { - } - }, false); + sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false); } log.info("HazelcastSessionManager started..."); @@ -235,8 +210,14 @@ public Session findSession(String id) throws IOException { sessions.put(id, hazelcastSession); // call remove method to trigger eviction Listener on each node to invalidate local sessions - sessionMap.remove(id); - sessionMap.set(id, hazelcastSession); + // the call are performed in a pessimistic lock block to prevent concurrency problems whilst finding sessions + sessionMap.lock(id); + try { + sessionMap.remove(id); + sessionMap.set(id, hazelcastSession); + } finally { + sessionMap.unlock(id); + } return hazelcastSession; } else { diff --git a/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index 87a1a20..e39ccb4 100644 --- a/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -4,11 +4,8 @@ package com.hazelcast.session; -import com.hazelcast.core.EntryEvent; -import com.hazelcast.core.EntryListener; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; -import com.hazelcast.core.MapEvent; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -91,29 +88,7 @@ public void startInternal() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryListener() { - public void entryAdded(EntryEvent event) { - } - - public void entryRemoved(EntryEvent entryEvent) { - if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) { - sessions.remove(entryEvent.getKey()); - } - } - - public void entryUpdated(EntryEvent event) { - } - - public void entryEvicted(EntryEvent entryEvent) { - entryRemoved(entryEvent); - } - - public void mapEvicted(MapEvent event) { - } - - public void mapCleared(MapEvent event) { - } - }, false); + sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false); } log.info("HazelcastSessionManager started..."); @@ -220,8 +195,14 @@ public Session findSession(String id) throws IOException { sessions.put(id, hazelcastSession); // call remove method to trigger eviction Listener on each node to invalidate local sessions - sessionMap.remove(id); - sessionMap.set(id, hazelcastSession); + // the call are performed in a pessimistic lock block to prevent concurrency problems whilst finding sessions + sessionMap.lock(id); + try { + sessionMap.remove(id); + sessionMap.set(id, hazelcastSession); + } finally { + sessionMap.unlock(id); + } return hazelcastSession; } else {