@@ -166,16 +166,22 @@ def _create_comm(self):
166
166
167
167
def destroy (self ):
168
168
self ._send_event ('close' )
169
- for comm in self .web_sockets .copy ():
169
+ # need to copy comms as callbacks will modify this list
170
+ for comm in list (self .web_sockets ):
170
171
comm .on_close ()
172
+ self .clearup_closed ()
171
173
172
174
def clearup_closed (self ):
173
175
"""Clear up any closed Comms."""
174
176
self .web_sockets = set ([socket for socket in self .web_sockets
175
177
if socket .is_open ()])
176
178
177
179
if len (self .web_sockets ) == 0 :
178
- self .manager .canvas .close_event ()
180
+ self .canvas .close_event ()
181
+
182
+ def remove_comm (self , comm_id ):
183
+ self .web_sockets = set ([socket for socket in self .web_sockets
184
+ if not socket .comm .comm_id == comm_id ])
179
185
180
186
181
187
class TimerTornado (TimerBase ):
@@ -278,15 +284,27 @@ def __init__(self, manager):
278
284
self .comm .on_msg (self .on_message )
279
285
280
286
manager = self .manager
281
- self .comm .on_close (lambda close_message : manager .clearup_closed ())
287
+ self ._ext_close = False
288
+
289
+ def _on_close (close_message ):
290
+ self ._ext_close = True
291
+ manager .remove_comm (close_message ['content' ]['comm_id' ])
292
+ manager .clearup_closed ()
293
+
294
+ self .comm .on_close (_on_close )
282
295
283
296
def is_open (self ):
284
- return not self .comm ._closed
297
+ return not ( self ._ext_close or self . comm ._closed )
285
298
286
299
def on_close (self ):
287
300
# When the socket is closed, deregister the websocket with
288
301
# the FigureManager.
289
- self .comm .close ()
302
+ if self .is_open ():
303
+ try :
304
+ self .comm .close ()
305
+ except KeyError :
306
+ # apparently already cleaned it up?
307
+ pass
290
308
291
309
def send_json (self , content ):
292
310
self .comm .send ({'data' : json .dumps (content )})
@@ -309,6 +327,7 @@ def on_message(self, message):
309
327
message = json .loads (message ['content' ]['data' ])
310
328
if message ['type' ] == 'closing' :
311
329
self .on_close ()
330
+ self .manager .clearup_closed ()
312
331
elif message ['type' ] == 'supports_binary' :
313
332
self .supports_binary = message ['value' ]
314
333
else :
0 commit comments