17
17
package org .springframework .messaging .simp .handler ;
18
18
19
19
import java .util .Collection ;
20
- import java .util .HashMap ;
21
20
import java .util .HashSet ;
22
21
import java .util .Map ;
23
22
import java .util .Set ;
29
28
import org .springframework .util .LinkedMultiValueMap ;
30
29
import org .springframework .util .MultiValueMap ;
31
30
31
+ import reactor .util .Assert ;
32
+
32
33
33
34
/**
34
35
* @author Rossen Stoyanchev
@@ -102,6 +103,14 @@ protected MultiValueMap<String, String> findSubscriptionsInternal(String destina
102
103
return result ;
103
104
}
104
105
106
+ @ Override
107
+ public String toString () {
108
+ return "[destinationCache=" + this .destinationCache + ", subscriptionRegistry="
109
+ + this .subscriptionRegistry + "]" ;
110
+ }
111
+
112
+
113
+
105
114
106
115
/**
107
116
* Provide direct lookup of session subscriptions by destination (for non-pattern destinations).
@@ -116,7 +125,7 @@ private static class DestinationCache {
116
125
117
126
118
127
public void mapToDestination (String destination , SessionSubscriptionInfo info ) {
119
- synchronized ( monitor ) {
128
+ synchronized ( this . monitor ) {
120
129
Set <SessionSubscriptionInfo > registrations = this .subscriptionsByDestination .get (destination );
121
130
if (registrations == null ) {
122
131
registrations = new CopyOnWriteArraySet <SessionSubscriptionInfo >();
@@ -127,7 +136,7 @@ public void mapToDestination(String destination, SessionSubscriptionInfo info) {
127
136
}
128
137
129
138
public void unmapFromDestination (String destination , SessionSubscriptionInfo info ) {
130
- synchronized ( monitor ) {
139
+ synchronized ( this . monitor ) {
131
140
Set <SessionSubscriptionInfo > infos = this .subscriptionsByDestination .get (destination );
132
141
if (infos != null ) {
133
142
infos .remove (info );
@@ -159,6 +168,11 @@ public MultiValueMap<String, String> getSubscriptions(String destination) {
159
168
}
160
169
return result ;
161
170
}
171
+
172
+ @ Override
173
+ public String toString () {
174
+ return "[subscriptionsByDestination=" + this .subscriptionsByDestination + "]" ;
175
+ }
162
176
}
163
177
164
178
/**
@@ -169,6 +183,8 @@ private static class SessionSubscriptionRegistry {
169
183
private final Map <String , SessionSubscriptionInfo > sessions =
170
184
new ConcurrentHashMap <String , SessionSubscriptionInfo >();
171
185
186
+ private final Object monitor = new Object ();
187
+
172
188
173
189
public SessionSubscriptionInfo getSubscriptions (String sessionId ) {
174
190
return this .sessions .get (sessionId );
@@ -181,16 +197,26 @@ public Collection<SessionSubscriptionInfo> getAllSubscriptions() {
181
197
public SessionSubscriptionInfo addSubscription (String sessionId , String subscriptionId , String destination ) {
182
198
SessionSubscriptionInfo info = this .sessions .get (sessionId );
183
199
if (info == null ) {
184
- info = new SessionSubscriptionInfo (sessionId );
185
- this .sessions .put (sessionId , info );
200
+ synchronized (this .monitor ) {
201
+ info = this .sessions .get (sessionId );
202
+ if (info == null ) {
203
+ info = new SessionSubscriptionInfo (sessionId );
204
+ this .sessions .put (sessionId , info );
205
+ }
206
+ }
186
207
}
187
- info .addSubscription (subscriptionId , destination );
208
+ info .addSubscription (destination , subscriptionId );
188
209
return info ;
189
210
}
190
211
191
212
public SessionSubscriptionInfo removeSubscriptions (String sessionId ) {
192
213
return this .sessions .remove (sessionId );
193
214
}
215
+
216
+ @ Override
217
+ public String toString () {
218
+ return "[sessions=" + sessions + "]" ;
219
+ }
194
220
}
195
221
196
222
/**
@@ -200,10 +226,13 @@ private static class SessionSubscriptionInfo {
200
226
201
227
private final String sessionId ;
202
228
203
- private final Map <String , Set <String >> subscriptions = new HashMap <String , Set <String >>(4 );
229
+ private final Map <String , Set <String >> subscriptions = new ConcurrentHashMap <String , Set <String >>(4 );
230
+
231
+ private final Object monitor = new Object ();
204
232
205
233
206
234
public SessionSubscriptionInfo (String sessionId ) {
235
+ Assert .notNull (sessionId , "sessionId is required" );
207
236
this .sessionId = sessionId ;
208
237
}
209
238
@@ -219,27 +248,36 @@ public Set<String> getSubscriptions(String destination) {
219
248
return this .subscriptions .get (destination );
220
249
}
221
250
222
- public void addSubscription (String subscriptionId , String destination ) {
223
- Set <String > subs = this .subscriptions .get (destination );
224
- if (subs == null ) {
225
- subs = new HashSet <String >(4 );
226
- this .subscriptions .put (destination , subs );
251
+ public void addSubscription (String destination , String subscriptionId ) {
252
+ synchronized (this .monitor ) {
253
+ Set <String > subs = this .subscriptions .get (destination );
254
+ if (subs == null ) {
255
+ subs = new HashSet <String >(4 );
256
+ this .subscriptions .put (destination , subs );
257
+ }
258
+ subs .add (subscriptionId );
227
259
}
228
- subs .add (subscriptionId );
229
260
}
230
261
231
262
public String removeSubscription (String subscriptionId ) {
232
263
for (String destination : this .subscriptions .keySet ()) {
233
264
Set <String > subscriptionIds = this .subscriptions .get (destination );
234
265
if (subscriptionIds .remove (subscriptionId )) {
235
- if (subscriptionIds .isEmpty ()) {
236
- this .subscriptions .remove (destination );
266
+ synchronized (this .monitor ) {
267
+ if (subscriptionIds .isEmpty ()) {
268
+ this .subscriptions .remove (destination );
269
+ }
237
270
}
238
271
return destination ;
239
272
}
240
273
}
241
274
return null ;
242
275
}
276
+
277
+ @ Override
278
+ public String toString () {
279
+ return "[sessionId=" + this .sessionId + ", subscriptions=" + this .subscriptions + "]" ;
280
+ }
243
281
}
244
282
245
283
}
0 commit comments