4747import java .util .Date ;
4848import java .util .HashMap ;
4949import java .util .HashSet ;
50- import java .util .LinkedList ;
50+ import java .util .Iterator ;
5151import java .util .List ;
5252import java .util .Map ;
5353import java .util .Map .Entry ;
@@ -69,7 +69,7 @@ public class ConnectionManager {
6969
7070 final Queue <NotebookSocket > connectedSockets = Metrics .gaugeCollectionSize ("zeppelin_connected_sockets" , Tags .empty (), new ConcurrentLinkedQueue <>());
7171 // noteId -> connection
72- final Map <String , List <NotebookSocket >> noteSocketMap = Metrics .gaugeMapSize ("zeppelin_note_sockets" , Tags .empty (), new HashMap <>());
72+ final Map <String , Set <NotebookSocket >> noteSocketMap = Metrics .gaugeMapSize ("zeppelin_note_sockets" , Tags .empty (), new HashMap <>());
7373 // user -> connection
7474 final Map <String , Queue <NotebookSocket >> userSocketMap = Metrics .gaugeMapSize ("zeppelin_user_sockets" , Tags .empty (), new HashMap <>());
7575
@@ -107,11 +107,9 @@ public void addNoteConnection(String noteId, NotebookSocket socket) {
107107 synchronized (noteSocketMap ) {
108108 // make sure a socket relates only an single note.
109109 removeConnectionFromAllNote (socket );
110- List <NotebookSocket > socketList = noteSocketMap .computeIfAbsent (noteId , k -> new LinkedList <>());
111- if (!socketList .contains (socket )) {
112- socketList .add (socket );
113- }
114- checkCollaborativeStatus (noteId , socketList );
110+ Set <NotebookSocket > sockets = noteSocketMap .computeIfAbsent (noteId , k -> new HashSet <>());
111+ sockets .add (socket );
112+ checkCollaborativeStatus (noteId , sockets );
115113 }
116114 }
117115
@@ -124,11 +122,33 @@ public void removeNoteConnection(String noteId) {
124122 public void removeNoteConnection (String noteId , NotebookSocket socket ) {
125123 LOGGER .debug ("Remove connection {} from note: {}" , socket , noteId );
126124 synchronized (noteSocketMap ) {
127- List <NotebookSocket > socketList = noteSocketMap .getOrDefault (noteId , Collections .emptyList ());
128- if (!socketList .isEmpty ()) {
129- socketList .remove (socket );
125+ Set <NotebookSocket > sockets = noteSocketMap .getOrDefault (noteId , Collections .emptySet ());
126+ removeNoteConnection (noteId , sockets , socket );
127+ // Remove empty socket collection from map
128+ if (sockets .isEmpty ()) {
129+ noteSocketMap .remove (noteId );
130+ }
131+ }
132+ }
133+
134+ private void removeNoteConnection (String noteId , Set <NotebookSocket > sockets ,
135+ NotebookSocket socket ) {
136+ sockets .remove (socket );
137+ checkCollaborativeStatus (noteId , sockets );
138+ }
139+
140+ public void removeConnectionFromAllNote (NotebookSocket socket ) {
141+ LOGGER .debug ("Remove connection {} from all notes" , socket );
142+ synchronized (noteSocketMap ) {
143+ Iterator <Entry <String , Set <NotebookSocket >>> iterator = noteSocketMap .entrySet ().iterator ();
144+ while (iterator .hasNext ()) {
145+ Entry <String , Set <NotebookSocket >> noteSocketMapEntry = iterator .next ();
146+ removeNoteConnection (noteSocketMapEntry .getKey (), noteSocketMapEntry .getValue (), socket );
147+ // Remove empty socket collection from map
148+ if (noteSocketMapEntry .getValue ().isEmpty ()) {
149+ iterator .remove ();
150+ }
130151 }
131- checkCollaborativeStatus (noteId , socketList );
132152 }
133153 }
134154
@@ -147,7 +167,11 @@ public void addUserConnection(String user, NotebookSocket conn) {
147167 public void removeUserConnection (String user , NotebookSocket conn ) {
148168 LOGGER .debug ("Remove user connection {} for user: {}" , conn , user );
149169 if (userSocketMap .containsKey (user )) {
150- userSocketMap .get (user ).remove (conn );
170+ Queue <NotebookSocket > connections = userSocketMap .get (user );
171+ connections .remove (conn );
172+ if (connections .isEmpty ()) {
173+ userSocketMap .remove (user );
174+ }
151175 } else {
152176 LOGGER .warn ("Closing connection that is absent in user connections" );
153177 }
@@ -156,7 +180,7 @@ public void removeUserConnection(String user, NotebookSocket conn) {
156180 public String getAssociatedNoteId (NotebookSocket socket ) {
157181 String associatedNoteId = null ;
158182 synchronized (noteSocketMap ) {
159- for (Entry <String , List <NotebookSocket >> noteSocketMapEntry : noteSocketMap .entrySet ()) {
183+ for (Entry <String , Set <NotebookSocket >> noteSocketMapEntry : noteSocketMap .entrySet ()) {
160184 if (noteSocketMapEntry .getValue ().contains (socket )) {
161185 associatedNoteId = noteSocketMapEntry .getKey ();
162186 }
@@ -166,16 +190,7 @@ public String getAssociatedNoteId(NotebookSocket socket) {
166190 return associatedNoteId ;
167191 }
168192
169- public void removeConnectionFromAllNote (NotebookSocket socket ) {
170- synchronized (noteSocketMap ) {
171- Set <String > noteIds = noteSocketMap .keySet ();
172- for (String noteId : noteIds ) {
173- removeNoteConnection (noteId , socket );
174- }
175- }
176- }
177-
178- private void checkCollaborativeStatus (String noteId , List <NotebookSocket > socketList ) {
193+ private void checkCollaborativeStatus (String noteId , Set <NotebookSocket > socketList ) {
179194 if (!collaborativeModeEnable .booleanValue ()) {
180195 return ;
181196 }
@@ -219,11 +234,11 @@ public void broadcast(String noteId, Message m) {
219234 List <NotebookSocket > socketsToBroadcast ;
220235 synchronized (noteSocketMap ) {
221236 broadcastToWatchers (noteId , StringUtils .EMPTY , m );
222- List <NotebookSocket > socketLists = noteSocketMap .get (noteId );
223- if (socketLists == null || socketLists .isEmpty ()) {
237+ Set <NotebookSocket > sockets = noteSocketMap .get (noteId );
238+ if (sockets == null || sockets .isEmpty ()) {
224239 return ;
225240 }
226- socketsToBroadcast = new ArrayList <>(socketLists );
241+ socketsToBroadcast = new ArrayList <>(sockets );
227242 }
228243 LOGGER .debug ("SEND >> {}" , m );
229244 for (NotebookSocket conn : socketsToBroadcast ) {
@@ -256,11 +271,11 @@ public void broadcastExcept(String noteId, Message m, NotebookSocket exclude) {
256271 List <NotebookSocket > socketsToBroadcast ;
257272 synchronized (noteSocketMap ) {
258273 broadcastToWatchers (noteId , StringUtils .EMPTY , m );
259- List <NotebookSocket > socketLists = noteSocketMap .get (noteId );
260- if (socketLists == null || socketLists .isEmpty ()) {
274+ Set <NotebookSocket > socketSet = noteSocketMap .get (noteId );
275+ if (socketSet == null || socketSet .isEmpty ()) {
261276 return ;
262277 }
263- socketsToBroadcast = new ArrayList <>(socketLists );
278+ socketsToBroadcast = new ArrayList <>(socketSet );
264279 }
265280
266281 LOGGER .debug ("SEND >> {}" , m );
0 commit comments