@@ -160,16 +160,22 @@ def _create_comm(self):
160
160
161
161
def destroy (self ):
162
162
self ._send_event ('close' )
163
- for comm in self .web_sockets .copy ():
163
+ # need to copy comms as callbacks will modify this list
164
+ for comm in list (self .web_sockets ):
164
165
comm .on_close ()
166
+ self .clearup_closed ()
165
167
166
168
def clearup_closed (self ):
167
169
"""Clear up any closed Comms."""
168
170
self .web_sockets = set ([socket for socket in self .web_sockets
169
171
if socket .is_open ()])
170
172
171
173
if len (self .web_sockets ) == 0 :
172
- self .manager .canvas .close_event ()
174
+ self .canvas .close_event ()
175
+
176
+ def remove_comm (self , comm_id ):
177
+ self .web_sockets = set ([socket for socket in self .web_sockets
178
+ if not socket .comm .comm_id == comm_id ])
173
179
174
180
175
181
class TimerTornado (TimerBase ):
@@ -267,15 +273,27 @@ def __init__(self, manager):
267
273
self .comm .on_msg (self .on_message )
268
274
269
275
manager = self .manager
270
- self .comm .on_close (lambda close_message : manager .clearup_closed ())
276
+ self ._ext_close = False
277
+
278
+ def _on_close (close_message ):
279
+ self ._ext_close = True
280
+ manager .remove_comm (close_message ['content' ]['comm_id' ])
281
+ manager .clearup_closed ()
282
+
283
+ self .comm .on_close (_on_close )
271
284
272
285
def is_open (self ):
273
- return not self .comm ._closed
286
+ return not ( self ._ext_close or self . comm ._closed )
274
287
275
288
def on_close (self ):
276
289
# When the socket is closed, deregister the websocket with
277
290
# the FigureManager.
278
- self .comm .close ()
291
+ if self .is_open ():
292
+ try :
293
+ self .comm .close ()
294
+ except KeyError :
295
+ # apparently already cleaned it up?
296
+ pass
279
297
280
298
def send_json (self , content ):
281
299
self .comm .send ({'data' : json .dumps (content )})
@@ -298,6 +316,7 @@ def on_message(self, message):
298
316
message = json .loads (message ['content' ]['data' ])
299
317
if message ['type' ] == 'closing' :
300
318
self .on_close ()
319
+ self .manager .clearup_closed ()
301
320
elif message ['type' ] == 'supports_binary' :
302
321
self .supports_binary = message ['value' ]
303
322
else :
0 commit comments