Skip to content

Commit

Permalink
Merge pull request #61 from alparslanavci/concurrent-session-fix/issu…
Browse files Browse the repository at this point in the history
…e#42

Updated the `findSession` method to fix concurrency issues
  • Loading branch information
alparslanavci authored Mar 18, 2019
2 parents bd40a60 + 1634467 commit 108f778
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 112 deletions.
Original file line number Diff line number Diff line change
@@ -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<String, HazelcastSession>,
EntryRemovedListener<String, HazelcastSession> {

private Map<String, Session> sessions;

public LocalSessionsInvalidateListener(Map<String, Session> sessions) {
this.sessions = sessions;
}

@Override
public void entryEvicted(EntryEvent<String, HazelcastSession> event) {
invalidateSessions(event);
}

@Override
public void entryRemoved(EntryEvent<String, HazelcastSession> event) {
invalidateSessions(event);
}

private void invalidateSessions(EntryEvent<String, HazelcastSession> entryEvent) {
if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) {
sessions.remove(entryEvent.getKey());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -124,29 +121,7 @@ public void start() throws LifecycleException {
}

if (!isSticky()) {
sessionMap.addEntryListener(new EntryListener<String, HazelcastSession>() {
public void entryAdded(EntryEvent<String, HazelcastSession> event) {
}

public void entryRemoved(EntryEvent<String, HazelcastSession> entryEvent) {
if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) {
sessions.remove(entryEvent.getKey());
}
}

public void entryUpdated(EntryEvent<String, HazelcastSession> event) {
}

public void entryEvicted(EntryEvent<String, HazelcastSession> entryEvent) {
entryRemoved(entryEvent);
}

public void mapEvicted(MapEvent event) {
}

public void mapCleared(MapEvent event) {
}
}, false);
sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false);
}

log.info("HazelcastSessionManager started...");
Expand Down Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -111,29 +108,7 @@ public void startInternal() throws LifecycleException {
}

if (!isSticky()) {
sessionMap.addEntryListener(new EntryListener<String, HazelcastSession>() {
public void entryAdded(EntryEvent<String, HazelcastSession> event) {
}

public void entryRemoved(EntryEvent<String, HazelcastSession> entryEvent) {
if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) {
sessions.remove(entryEvent.getKey());
}
}

public void entryUpdated(EntryEvent<String, HazelcastSession> event) {
}

public void entryEvicted(EntryEvent<String, HazelcastSession> entryEvent) {
entryRemoved(entryEvent);
}

public void mapEvicted(MapEvent event) {
}

public void mapCleared(MapEvent event) {
}
}, false);
sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false);
}

log.info("HazelcastSessionManager started...");
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -109,29 +106,7 @@ public void startInternal() throws LifecycleException {
}

if (!isSticky()) {
sessionMap.addEntryListener(new EntryListener<String, HazelcastSession>() {
public void entryAdded(EntryEvent<String, HazelcastSession> event) {
}

public void entryRemoved(EntryEvent<String, HazelcastSession> entryEvent) {
if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) {
sessions.remove(entryEvent.getKey());
}
}

public void entryUpdated(EntryEvent<String, HazelcastSession> event) {
}

public void entryEvicted(EntryEvent<String, HazelcastSession> entryEvent) {
entryRemoved(entryEvent);
}

public void mapEvicted(MapEvent event) {
}

public void mapCleared(MapEvent event) {
}
}, false);
sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false);
}

log.info("HazelcastSessionManager started...");
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -91,29 +88,7 @@ public void startInternal() throws LifecycleException {
}

if (!isSticky()) {
sessionMap.addEntryListener(new EntryListener<String, HazelcastSession>() {
public void entryAdded(EntryEvent<String, HazelcastSession> event) {
}

public void entryRemoved(EntryEvent<String, HazelcastSession> entryEvent) {
if (entryEvent.getMember() == null || !entryEvent.getMember().localMember()) {
sessions.remove(entryEvent.getKey());
}
}

public void entryUpdated(EntryEvent<String, HazelcastSession> event) {
}

public void entryEvicted(EntryEvent<String, HazelcastSession> entryEvent) {
entryRemoved(entryEvent);
}

public void mapEvicted(MapEvent event) {
}

public void mapCleared(MapEvent event) {
}
}, false);
sessionMap.addEntryListener(new LocalSessionsInvalidateListener(sessions), false);
}

log.info("HazelcastSessionManager started...");
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 108f778

Please sign in to comment.