@@ -70,7 +70,6 @@ def shutdown():
70
70
print ("Shutdown proxy subscriber ..." )
71
71
ProxySubscriberCached ._topics .clear ()
72
72
ProxySubscriberCached ._persistant_topics .clear ()
73
- ProxySubscriberCached ._node = None
74
73
75
74
except Exception as exc : # pylint: disable=W0703
76
75
print (f'Something went wrong during shutdown of proxy subscriber !\n { str (exc )} ' )
@@ -156,7 +155,8 @@ def subscribe(cls, topic, msg_type, callback=None, buffered=False, qos=None, ins
156
155
f"({ len (ProxySubscriberCached ._topics [topic ]['subscribers' ])} )" )
157
156
158
157
# Register the local callback for topic message
159
- cls .set_callback (topic , callback , inst_id )
158
+ if callback is not None :
159
+ cls .set_callback (topic , callback , inst_id )
160
160
161
161
@classmethod
162
162
def _callback (cls , msg , topic ):
@@ -173,16 +173,18 @@ def _callback(cls, msg, topic):
173
173
Logger .localinfo (f"-- invalid topic={ topic } for callback!" )
174
174
return
175
175
176
- ProxySubscriberCached ._topics [topic ]['last_msg' ] = msg
177
- if ProxySubscriberCached ._topics [topic ]['buffered' ]:
178
- ProxySubscriberCached ._topics [topic ]['msg_queue' ].append (msg )
179
-
180
- for inst_id , callback in ProxySubscriberCached ._topics [topic ]['callbacks' ].items ():
181
- try :
182
- callback (msg )
183
- except Exception as exc : # pylint: disable=W0703
184
- Logger .error (f"Exception in callback for { topic } : "
185
- f"{ callback .__module__ } { callback .__name__ } @ { inst_id } \n { exc } " )
176
+ try :
177
+ ProxySubscriberCached ._topics [topic ]['last_msg' ] = msg
178
+ if ProxySubscriberCached ._topics [topic ]['buffered' ]:
179
+ ProxySubscriberCached ._topics [topic ]['msg_queue' ].append (msg )
180
+ for inst_id , callback in ProxySubscriberCached ._topics [topic ]['callbacks' ].items ():
181
+ try :
182
+ callback (msg )
183
+ except Exception as exc : # pylint: disable=W0703
184
+ Logger .error (f"Exception in callback for { topic } : "
185
+ f"{ callback .__module__ } { callback .__name__ } @ { inst_id } \n { exc } " )
186
+ except KeyError :
187
+ Logger .error (f"Error: { topic } is no longer available for processing callback! " )
186
188
187
189
@classmethod
188
190
def set_callback (cls , topic , callback , inst_id = - 1 ):
@@ -203,16 +205,24 @@ def set_callback(cls, topic, callback, inst_id=-1):
203
205
return
204
206
205
207
if callback is not None :
208
+ ProxySubscriberCached ._node .executor .create_task (cls .__set_callback , topic , callback , inst_id )
209
+
210
+ @classmethod
211
+ def __set_callback (cls , topic , callback , inst_id ):
212
+ """Set callback in executor thread."""
213
+ try :
206
214
if inst_id not in ProxySubscriberCached ._topics [topic ]['callbacks' ]:
207
215
ProxySubscriberCached ._topics [topic ]['callbacks' ][inst_id ] = callback
208
216
Logger .localinfo (f" Set local callback { callback .__name__ } of "
209
- f"{ len (ProxySubscriberCached ._topics [topic ]['callbacks' ])} for { topic } !" )
217
+ f"{ len (ProxySubscriberCached ._topics [topic ]['callbacks' ])} for { topic } !" )
210
218
else :
211
219
Logger .localinfo ("Update existing callback "
212
- f"{ ProxySubscriberCached ._topics [topic ]['callbacks' ][inst_id ].__name__ } with "
213
- f"{ callback .__name__ } of { len (ProxySubscriberCached ._topics [topic ]['callbacks' ])} "
214
- f" for { topic } !" )
220
+ f"{ ProxySubscriberCached ._topics [topic ]['callbacks' ][inst_id ].__name__ } with "
221
+ f"{ callback .__name__ } of { len (ProxySubscriberCached ._topics [topic ]['callbacks' ])} "
222
+ f" for { topic } !" )
215
223
ProxySubscriberCached ._topics [topic ]['callbacks' ][inst_id ] = callback
224
+ except KeyError :
225
+ Logger .localwarn ("Error: topic {topic} is not longer available - cannot set callback!" )
216
226
217
227
@classmethod
218
228
def enable_buffer (cls , topic ):
@@ -307,9 +317,13 @@ def remove_last_msg(cls, topic, clear_buffer=False):
307
317
"""
308
318
if topic in ProxySubscriberCached ._persistant_topics :
309
319
return
310
- ProxySubscriberCached ._topics [topic ]['last_msg' ] = None
311
- if clear_buffer :
312
- ProxySubscriberCached ._topics [topic ]['msg_queue' ] = []
320
+
321
+ try :
322
+ ProxySubscriberCached ._topics [topic ]['last_msg' ] = None
323
+ if clear_buffer :
324
+ ProxySubscriberCached ._topics [topic ]['msg_queue' ] = []
325
+ except KeyError :
326
+ Logger .localwarn (f"remove_last_msg: { topic } is not available!" )
313
327
314
328
@classmethod
315
329
def make_persistant (cls , topic ):
@@ -343,20 +357,18 @@ def unsubscribe_topic(cls, topic, inst_id=-1):
343
357
topic_dict ['subscribers' ].remove (inst_id )
344
358
Logger .localinfo (f"Unsubscribed { topic } from proxy! "
345
359
f"({ len (topic_dict ['subscribers' ])} remaining)" )
346
-
347
- if inst_id in topic_dict ['callbacks' ]:
348
- topic_dict ['callbacks' ].pop (inst_id )
349
- Logger .localinfo (f"Removed callback from proxy subscription for { topic } "
350
- f"from proxy! ({ len (topic_dict ['callbacks' ])} remaining)" )
351
-
352
- remaining_subscribers = len (topic_dict ['subscribers' ])
353
- remaining_callbacks = len (topic_dict ['callbacks' ])
354
- if remaining_subscribers == 0 :
355
- assert remaining_callbacks == 0 , "Must have at least one subscriber tracked for every callback!"
356
- sub = topic_dict ['subscription' ]
357
- ProxySubscriberCached ._topics .pop (topic )
358
- ProxySubscriberCached ._node .executor .create_task (ProxySubscriberCached .destroy_subscription ,
359
- sub , topic )
360
+
361
+ remaining_subscribers = len (topic_dict ['subscribers' ])
362
+ if remaining_subscribers == 0 :
363
+ ProxySubscriberCached ._topics .pop (topic ) # remove from list of valid topics
364
+ sub = topic_dict ['subscription' ]
365
+ ProxySubscriberCached ._node .executor .create_task (ProxySubscriberCached .destroy_subscription ,
366
+ sub , topic )
367
+ elif inst_id in topic_dict ['callbacks' ]:
368
+ # Remove callback in executor thread to avoid changing size during callback
369
+ ProxySubscriberCached ._node .executor .create_task (topic_dict ['callbacks' ].pop , inst_id )
370
+ Logger .localinfo (f"Removed callback from proxy subscription for { topic } "
371
+ f"from proxy! ({ len (topic_dict ['callbacks' ])} remaining)" )
360
372
361
373
except Exception as exc : # pylint: disable=W0703
362
374
Logger .error (f'Something went wrong unsubscribing { topic } of proxy subscriber!\n %s' , str (exc ))
0 commit comments