|
22 | 22 |
|
23 | 23 | import java.net.URI; |
24 | 24 | import java.util.Collection; |
| 25 | +import java.util.Collections; |
25 | 26 | import java.util.HashMap; |
26 | 27 | import java.util.HashSet; |
27 | 28 | import java.util.Map; |
28 | 29 | import java.util.Set; |
29 | 30 | import java.util.concurrent.ConcurrentHashMap; |
30 | 31 | import java.util.concurrent.ConcurrentMap; |
| 32 | +import java.util.concurrent.locks.Lock; |
31 | 33 | import java.util.concurrent.locks.ReadWriteLock; |
32 | 34 | import java.util.concurrent.locks.ReentrantReadWriteLock; |
33 | 35 | import java.util.logging.Logger; |
@@ -115,14 +117,9 @@ public boolean add(Session session) { |
115 | 117 | public Session get(SessionId id) { |
116 | 118 | Require.nonNull("Session ID", id); |
117 | 119 |
|
118 | | - Session session = knownSessions.get(id); |
119 | | - if (session != null) { |
120 | | - return session; |
121 | | - } |
122 | | - |
123 | 120 | sessionMapLock.readLock().lock(); |
124 | 121 | try { |
125 | | - session = knownSessions.get(id); |
| 122 | + Session session = knownSessions.get(id); |
126 | 123 | if (session == null) { |
127 | 124 | throw new NoSuchSessionException("Unable to find session with ID: " + id); |
128 | 125 | } |
@@ -201,6 +198,8 @@ private void batchRemoveByUri(URI externalUri, Class<? extends Event> eventClass |
201 | 198 | private static class IndexedSessionMap { |
202 | 199 | private final ConcurrentMap<SessionId, Session> sessions = new ConcurrentHashMap<>(); |
203 | 200 | private final ConcurrentMap<URI, Set<SessionId>> sessionsByUri = new ConcurrentHashMap<>(); |
| 201 | + private final ReadWriteLock lock = new ReentrantReadWriteLock(); |
| 202 | + private final Lock writeLock = lock.writeLock(); |
204 | 203 |
|
205 | 204 | public Session get(SessionId id) { |
206 | 205 | return sessions.get(id); |
@@ -242,29 +241,34 @@ public Session remove(SessionId id) { |
242 | 241 | } |
243 | 242 |
|
244 | 243 | public void batchRemove(Set<SessionId> sessionIds) { |
245 | | - Map<URI, Set<SessionId>> uriToSessionIds = new HashMap<>(); |
246 | | - |
247 | | - for (SessionId id : sessionIds) { |
248 | | - Session session = sessions.get(id); |
249 | | - if (session != null && session.getUri() != null) { |
250 | | - uriToSessionIds.computeIfAbsent(session.getUri(), k -> new HashSet<>()).add(id); |
| 244 | + writeLock.lock(); |
| 245 | + try { |
| 246 | + Map<URI, Set<SessionId>> uriToSessionIds = new HashMap<>(); |
| 247 | + |
| 248 | + for (SessionId id : sessionIds) { |
| 249 | + Session session = sessions.get(id); |
| 250 | + if (session != null && session.getUri() != null) { |
| 251 | + uriToSessionIds.computeIfAbsent(session.getUri(), k -> new HashSet<>()).add(id); |
| 252 | + } |
251 | 253 | } |
252 | | - } |
253 | 254 |
|
254 | | - for (SessionId id : sessionIds) { |
255 | | - sessions.remove(id); |
256 | | - } |
| 255 | + for (SessionId id : sessionIds) { |
| 256 | + sessions.remove(id); |
| 257 | + } |
257 | 258 |
|
258 | | - for (Map.Entry<URI, Set<SessionId>> entry : uriToSessionIds.entrySet()) { |
259 | | - URI uri = entry.getKey(); |
260 | | - Set<SessionId> idsToRemove = entry.getValue(); |
| 259 | + for (Map.Entry<URI, Set<SessionId>> entry : uriToSessionIds.entrySet()) { |
| 260 | + URI uri = entry.getKey(); |
| 261 | + Set<SessionId> idsToRemove = entry.getValue(); |
261 | 262 |
|
262 | | - sessionsByUri.computeIfPresent( |
263 | | - uri, |
264 | | - (k, existingIds) -> { |
265 | | - existingIds.removeAll(idsToRemove); |
266 | | - return existingIds.isEmpty() ? null : existingIds; |
267 | | - }); |
| 263 | + sessionsByUri.computeIfPresent( |
| 264 | + uri, |
| 265 | + (k, existingIds) -> { |
| 266 | + existingIds.removeAll(idsToRemove); |
| 267 | + return existingIds.isEmpty() ? null : existingIds; |
| 268 | + }); |
| 269 | + } |
| 270 | + } finally { |
| 271 | + writeLock.unlock(); |
268 | 272 | } |
269 | 273 | } |
270 | 274 |
|
|
0 commit comments