Commit 641cdac9 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

More cluster cache work. We are now locking not only the same cache but the same entry.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/branches@10076 b35dd754-fafc-0310-a699-88a17e54d16e
parent 48238d0e
...@@ -591,7 +591,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener ...@@ -591,7 +591,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
* the session unavailable means that the session is not eligible for receiving messages from * the session unavailable means that the session is not eligible for receiving messages from
* other clients. * other clients.
* *
* @param session the session that receieved an unavailable presence. * @param session the session that received an unavailable presence.
*/ */
public void sessionUnavailable(LocalClientSession session) { public void sessionUnavailable(LocalClientSession session) {
if (session.getAddress() != null && routingTable != null && if (session.getAddress() != null && routingTable != null &&
......
...@@ -323,7 +323,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -323,7 +323,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
* @param name the discovered name of the component. * @param name the discovered name of the component.
*/ */
public void addComponentItem(String jid, String node, String name) { public void addComponentItem(String jid, String node, String name) {
Lock lock = CacheFactory.getLock(jid + "item", serverItems); Lock lock = CacheFactory.getLock(jid, serverItems);
try { try {
lock.lock(); lock.lock();
ClusteredServerItem item = serverItems.get(jid); ClusteredServerItem item = serverItems.get(jid);
...@@ -359,7 +359,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -359,7 +359,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
// Safety check // Safety check
return; return;
} }
Lock lock = CacheFactory.getLock(jid + "item", serverItems); Lock lock = CacheFactory.getLock(jid, serverItems);
try { try {
lock.lock(); lock.lock();
ClusteredServerItem item = serverItems.get(jid); ClusteredServerItem item = serverItems.get(jid);
...@@ -425,7 +425,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -425,7 +425,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
NodeID leftNode = NodeID.getInstance(nodeID); NodeID leftNode = NodeID.getInstance(nodeID);
for (Map.Entry<String, ClusteredServerItem> entry : serverItems.entrySet()) { for (Map.Entry<String, ClusteredServerItem> entry : serverItems.entrySet()) {
String jid = entry.getKey(); String jid = entry.getKey();
Lock lock = CacheFactory.getLock(jid + "item", serverItems); Lock lock = CacheFactory.getLock(jid, serverItems);
try { try {
lock.lock(); lock.lock();
ClusteredServerItem item = entry.getValue(); ClusteredServerItem item = entry.getValue();
...@@ -453,7 +453,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -453,7 +453,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
for (Map.Entry<String, Element> entry : localServerItems.entrySet()) { for (Map.Entry<String, Element> entry : localServerItems.entrySet()) {
String jid = entry.getKey(); String jid = entry.getKey();
Element element = entry.getValue(); Element element = entry.getValue();
Lock lock = CacheFactory.getLock(jid + "item", serverItems); Lock lock = CacheFactory.getLock(jid, serverItems);
try { try {
lock.lock(); lock.lock();
ClusteredServerItem item = serverItems.get(jid); ClusteredServerItem item = serverItems.get(jid);
......
...@@ -35,6 +35,7 @@ import java.util.HashMap; ...@@ -35,6 +35,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.Lock;
/** /**
* Implements the presence protocol. Clients use this protocol to * Implements the presence protocol. Clients use this protocol to
...@@ -352,6 +353,9 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler ...@@ -352,6 +353,9 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler
} }
if (keepTrack) { if (keepTrack) {
String sender = update.getFrom().toString(); String sender = update.getFrom().toString();
Lock lock = CacheFactory.getLock(sender, directedPresencesCache);
try {
lock.lock();
Collection<DirectedPresence> directedPresences = directedPresencesCache.get(sender); Collection<DirectedPresence> directedPresences = directedPresencesCache.get(sender);
if (Presence.Type.unavailable.equals(update.getType())) { if (Presence.Type.unavailable.equals(update.getType())) {
if (directedPresences != null) { if (directedPresences != null) {
...@@ -420,6 +424,9 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler ...@@ -420,6 +424,9 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler
directedPresencesCache.put(sender, directedPresences); directedPresencesCache.put(sender, directedPresences);
localDirectedPresences.put(sender, directedPresences); localDirectedPresences.put(sender, directedPresences);
} }
} finally {
lock.unlock();
}
} }
} }
} }
...@@ -437,7 +444,16 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler ...@@ -437,7 +444,16 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler
} }
if (localServer.isLocal(from)) { if (localServer.isLocal(from)) {
// Remove the registry of directed presences of this user // Remove the registry of directed presences of this user
Collection<DirectedPresence> directedPresences = directedPresencesCache.remove(from.toString()); Collection<DirectedPresence> directedPresences = null;
Lock lock = CacheFactory.getLock(from.toString(), directedPresencesCache);
try {
lock.lock();
directedPresences = directedPresencesCache.remove(from.toString());
} finally {
lock.unlock();
}
if (directedPresences != null) { if (directedPresences != null) {
// Iterate over all the entities that the user sent a directed presence // Iterate over all the entities that the user sent a directed presence
for (DirectedPresence directedPresence : directedPresences) { for (DirectedPresence directedPresence : directedPresences) {
...@@ -516,7 +532,19 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler ...@@ -516,7 +532,19 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler
entry.getKey()); entry.getKey());
continue; continue;
} }
// TODO perhaps we should not lock for every entry. Instead, lock it
// once (using a LOCK_ALL global key), and handle iterations in
// one go. We should first make sure that this doesn't lead to
// deadlocks though! The tryLock() mechanism could be used to first
// try one approach, but fall back on the other approach.
Lock lock = CacheFactory.getLock(entry.getKey(), directedPresencesCache);
try {
lock.lock();
directedPresencesCache.put(entry.getKey(), entry.getValue()); directedPresencesCache.put(entry.getKey(), entry.getValue());
} finally {
lock.unlock();
}
} }
} }
...@@ -534,7 +562,20 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler ...@@ -534,7 +562,20 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler
entry.getKey()); entry.getKey());
continue; continue;
} }
// TODO perhaps we should not lock for every entry. Instead, lock it
// once (using a LOCK_ALL global key), and handle iterations in
// one go. We should first make sure that this doesn't lead to
// deadlocks though! The tryLock() mechanism could be used to first
// try one approach, but fall back on the other approach.
Lock lock = CacheFactory.getLock(entry.getKey(), directedPresencesCache);
try {
lock.lock();
directedPresencesCache.put(entry.getKey(), entry.getValue()); directedPresencesCache.put(entry.getKey(), entry.getValue());
} finally {
lock.unlock();
}
} }
} }
} }
......
...@@ -207,7 +207,7 @@ public class OutgoingSessionPromise implements RoutableChannelHandler { ...@@ -207,7 +207,7 @@ public class OutgoingSessionPromise implements RoutableChannelHandler {
// Create a connection to the remote server from the domain where the packet has been sent // Create a connection to the remote server from the domain where the packet has been sent
boolean created; boolean created;
// Make sure that only one cluster node is creating the outgoing connection // Make sure that only one cluster node is creating the outgoing connection
Lock lock = CacheFactory.getLock(domain + "oss", serversCache); Lock lock = CacheFactory.getLock(domain, serversCache);
try { try {
lock.lock(); lock.lock();
created = LocalOutgoingServerSession created = LocalOutgoingServerSession
......
...@@ -502,7 +502,7 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager ...@@ -502,7 +502,7 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null; ResultSet rs = null;
Lock lock = CacheFactory.getLock(username + "pr", offlinePresenceCache); Lock lock = CacheFactory.getLock(username, offlinePresenceCache);
try { try {
lock.lock(); lock.lock();
if (!offlinePresenceCache.containsKey(username) || !lastActivityCache.containsKey(username)) { if (!offlinePresenceCache.containsKey(username) || !lastActivityCache.containsKey(username)) {
......
...@@ -108,7 +108,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -108,7 +108,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
public void addComponentRoute(JID route, RoutableChannelHandler destination) { public void addComponentRoute(JID route, RoutableChannelHandler destination) {
String address = route.getDomain(); String address = route.getDomain();
localRoutingTable.addRoute(address, destination); localRoutingTable.addRoute(address, destination);
Lock lock = CacheFactory.getLock(address + "rt", componentsCache); Lock lock = CacheFactory.getLock(address, componentsCache);
try { try {
lock.lock(); lock.lock();
Set<NodeID> nodes = componentsCache.get(address); Set<NodeID> nodes = componentsCache.get(address);
...@@ -663,7 +663,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -663,7 +663,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
public boolean removeComponentRoute(JID route) { public boolean removeComponentRoute(JID route) {
String address = route.getDomain(); String address = route.getDomain();
boolean removed = false; boolean removed = false;
Lock lock = CacheFactory.getLock(address + "rt", componentsCache); Lock lock = CacheFactory.getLock(address, componentsCache);
try { try {
lock.lock(); lock.lock();
Set<NodeID> nodes = componentsCache.get(address); Set<NodeID> nodes = componentsCache.get(address);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment