From 110103e5930fc5d6e347f4445585eeb89372cc92 Mon Sep 17 00:00:00 2001 From: alparslanavci Date: Thu, 14 Mar 2019 15:31:53 +0000 Subject: [PATCH 1/3] Updated the `findSession` method to fix concurrency issues with Hazelcast calls --- .../session/HazelcastSessionManager.java | 32 +++++++------------ .../session/HazelcastSessionManager.java | 32 +++++++------------ .../session/HazelcastSessionManager.java | 32 +++++++------------ .../session/HazelcastSessionManager.java | 32 +++++++------------ 4 files changed, 44 insertions(+), 84 deletions(-) diff --git a/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index ff8086d..f7b155b 100644 --- a/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -5,10 +5,9 @@ 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 com.hazelcast.map.listener.EntryRemovedListener; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -124,28 +123,13 @@ public void start() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryListener() { - public void entryAdded(EntryEvent event) { - } - + sessionMap.addEntryListener(new EntryRemovedListener() { + @Override 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); } @@ -238,8 +222,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..1ff04d5 100644 --- a/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -5,10 +5,9 @@ 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 com.hazelcast.map.listener.EntryRemovedListener; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -111,28 +110,13 @@ public void startInternal() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryListener() { - public void entryAdded(EntryEvent event) { - } - + sessionMap.addEntryListener(new EntryRemovedListener() { + @Override 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); } @@ -237,8 +221,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..7a49284 100644 --- a/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -5,10 +5,9 @@ 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 com.hazelcast.map.listener.EntryRemovedListener; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -109,28 +108,13 @@ public void startInternal() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryListener() { - public void entryAdded(EntryEvent event) { - } - + sessionMap.addEntryListener(new EntryRemovedListener() { + @Override 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); } @@ -235,8 +219,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..6fca138 100644 --- a/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -5,10 +5,9 @@ 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 com.hazelcast.map.listener.EntryRemovedListener; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -91,28 +90,13 @@ public void startInternal() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryListener() { - public void entryAdded(EntryEvent event) { - } - + sessionMap.addEntryListener(new EntryRemovedListener() { + @Override 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); } @@ -220,8 +204,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 { From 2094e7854d98f7a28aabf97eee31343cfdaee73c Mon Sep 17 00:00:00 2001 From: alparslanavci Date: Thu, 14 Mar 2019 17:11:15 +0000 Subject: [PATCH 2/3] Added the missing expired event calls --- .../LocalSessionsInvalidateListener.java | 34 +++++++++++++++++++ .../session/HazelcastSessionManager.java | 11 +----- .../session/HazelcastSessionManager.java | 11 +----- .../session/HazelcastSessionManager.java | 11 +----- .../session/HazelcastSessionManager.java | 9 +---- 5 files changed, 38 insertions(+), 38 deletions(-) create mode 100644 tomcat-core/src/main/java/com/hazelcast/session/LocalSessionsInvalidateListener.java 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..7d1bf39 --- /dev/null +++ b/tomcat-core/src/main/java/com/hazelcast/session/LocalSessionsInvalidateListener.java @@ -0,0 +1,34 @@ +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 f7b155b..d427cdf 100644 --- a/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -4,10 +4,8 @@ package com.hazelcast.session; -import com.hazelcast.core.EntryEvent; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; -import com.hazelcast.map.listener.EntryRemovedListener; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -123,14 +121,7 @@ public void start() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryRemovedListener() { - @Override - public void entryRemoved(EntryEvent entryEvent) { - if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) { - sessions.remove(entryEvent.getKey()); - } - } - }, false); + sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false); } log.info("HazelcastSessionManager started..."); diff --git a/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index 1ff04d5..ea33184 100644 --- a/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -4,10 +4,8 @@ package com.hazelcast.session; -import com.hazelcast.core.EntryEvent; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; -import com.hazelcast.map.listener.EntryRemovedListener; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -110,14 +108,7 @@ public void startInternal() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryRemovedListener() { - @Override - public void entryRemoved(EntryEvent entryEvent) { - if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) { - sessions.remove(entryEvent.getKey()); - } - } - }, false); + sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false); } log.info("HazelcastSessionManager started..."); diff --git a/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index 7a49284..64715c2 100644 --- a/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -4,10 +4,8 @@ package com.hazelcast.session; -import com.hazelcast.core.EntryEvent; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; -import com.hazelcast.map.listener.EntryRemovedListener; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; @@ -108,14 +106,7 @@ public void startInternal() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryRemovedListener() { - @Override - public void entryRemoved(EntryEvent entryEvent) { - if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) { - sessions.remove(entryEvent.getKey()); - } - } - }, false); + sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false); } log.info("HazelcastSessionManager started..."); diff --git a/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index 6fca138..b62fd04 100644 --- a/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -90,14 +90,7 @@ public void startInternal() throws LifecycleException { } if (!isSticky()) { - sessionMap.addEntryListener(new EntryRemovedListener() { - @Override - public void entryRemoved(EntryEvent entryEvent) { - if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) { - sessions.remove(entryEvent.getKey()); - } - } - }, false); + sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false); } log.info("HazelcastSessionManager started..."); From 16344677534737e6a1ccf001ddcfaf78fcbbeec4 Mon Sep 17 00:00:00 2001 From: alparslanavci Date: Thu, 14 Mar 2019 17:14:05 +0000 Subject: [PATCH 3/3] Checkstyle fixes --- .../hazelcast/session/LocalSessionsInvalidateListener.java | 4 ++++ .../java/com/hazelcast/session/HazelcastSessionManager.java | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tomcat-core/src/main/java/com/hazelcast/session/LocalSessionsInvalidateListener.java b/tomcat-core/src/main/java/com/hazelcast/session/LocalSessionsInvalidateListener.java index 7d1bf39..eba129b 100644 --- a/tomcat-core/src/main/java/com/hazelcast/session/LocalSessionsInvalidateListener.java +++ b/tomcat-core/src/main/java/com/hazelcast/session/LocalSessionsInvalidateListener.java @@ -1,3 +1,7 @@ +/* + * Copyright (c) 2008-2019, Hazelcast, Inc. All Rights Reserved. + */ + package com.hazelcast.session; import com.hazelcast.core.EntryEvent; diff --git a/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index b62fd04..e39ccb4 100644 --- a/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -4,10 +4,8 @@ package com.hazelcast.session; -import com.hazelcast.core.EntryEvent; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; -import com.hazelcast.map.listener.EntryRemovedListener; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException;