5
5
:meth:`can.BusABC.send_periodic`.
6
6
"""
7
7
8
- from typing import Optional , Sequence , Tuple , Union , TYPE_CHECKING
8
+ from typing import Optional , Sequence , Tuple , Union , Callable , TYPE_CHECKING
9
9
10
10
from can import typechecking
11
11
@@ -198,7 +198,7 @@ def __init__(
198
198
class ThreadBasedCyclicSendTask (
199
199
ModifiableCyclicTaskABC , LimitedDurationCyclicSendTaskABC , RestartableCyclicTaskABC
200
200
):
201
- """Fallback cyclic send task using thread."""
201
+ """Fallback cyclic send task using daemon thread."""
202
202
203
203
def __init__ (
204
204
self ,
@@ -207,13 +207,28 @@ def __init__(
207
207
messages : Union [Sequence [Message ], Message ],
208
208
period : float ,
209
209
duration : Optional [float ] = None ,
210
+ on_error : Optional [Callable [[Exception ], bool ]] = None ,
210
211
):
212
+ """Transmits `messages` with a `period` seconds for `duration` seconds on a `bus`.
213
+
214
+ The `on_error` is called if any error happens on `bus` while sending `messages`.
215
+ If `on_error` present, and returns ``False`` when invoked, thread is
216
+ stopped immediately, otherwise, thread continuiously tries to send `messages`
217
+ ignoring errors on a `bus`. Absence of `on_error` means that thread exits immediately
218
+ on error.
219
+
220
+ :param on_error: The callable that accepts an exception if any
221
+ error happened on a `bus` while sending `messages`,
222
+ it shall return either ``True`` or ``False`` depending
223
+ on desired behaviour of `ThreadBasedCyclicSendTask`.
224
+ """
211
225
super ().__init__ (messages , period , duration )
212
226
self .bus = bus
213
227
self .send_lock = lock
214
228
self .stopped = True
215
229
self .thread = None
216
230
self .end_time = time .perf_counter () + duration if duration else None
231
+ self .on_error = on_error
217
232
218
233
if HAS_EVENTS :
219
234
self .period_ms : int = int (round (period * 1000 , 0 ))
@@ -250,7 +265,11 @@ def _run(self):
250
265
self .bus .send (self .messages [msg_index ])
251
266
except Exception as exc :
252
267
log .exception (exc )
253
- break
268
+ if self .on_error :
269
+ if not self .on_error (exc ):
270
+ break
271
+ else :
272
+ break
254
273
if self .end_time is not None and time .perf_counter () >= self .end_time :
255
274
break
256
275
msg_index = (msg_index + 1 ) % len (self .messages )
0 commit comments