Skip to content

Commit abe0db5

Browse files
authored
Set end_time in ThreadBasedCyclicSendTask.start() (#1871)
1 parent a39e63e commit abe0db5

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

can/broadcastmanager.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ def __init__(
182182
"""
183183
super().__init__(messages, period)
184184
self.duration = duration
185+
self.end_time: Optional[float] = None
185186

186187

187188
class RestartableCyclicTaskABC(CyclicSendTaskABC, abc.ABC):
@@ -299,9 +300,6 @@ def __init__(
299300
self.send_lock = lock
300301
self.stopped = True
301302
self.thread: Optional[threading.Thread] = None
302-
self.end_time: Optional[float] = (
303-
time.perf_counter() + duration if duration else None
304-
)
305303
self.on_error = on_error
306304
self.modifier_callback = modifier_callback
307305

@@ -341,6 +339,10 @@ def start(self) -> None:
341339
self.thread = threading.Thread(target=self._run, name=name)
342340
self.thread.daemon = True
343341

342+
self.end_time: Optional[float] = (
343+
time.perf_counter() + self.duration if self.duration else None
344+
)
345+
344346
if self.event and PYWIN32:
345347
PYWIN32.set_timer(self.event, self.period_ms)
346348

@@ -356,6 +358,7 @@ def _run(self) -> None:
356358

357359
while not self.stopped:
358360
if self.end_time is not None and time.perf_counter() >= self.end_time:
361+
self.stop()
359362
break
360363

361364
try:

test/simplecyclic_test.py

+28-4
Original file line numberDiff line numberDiff line change
@@ -155,25 +155,49 @@ def test_stopping_perodic_tasks(self):
155155
def test_restart_perodic_tasks(self):
156156
period = 0.01
157157
safe_timeout = period * 5 if not IS_PYPY else 1.0
158+
duration = 0.3
158159

159160
msg = can.Message(
160161
is_extended_id=False, arbitration_id=0x123, data=[0, 1, 2, 3, 4, 5, 6, 7]
161162
)
162163

164+
def _read_all_messages(_bus: can.interfaces.virtual.VirtualBus) -> None:
165+
sleep(safe_timeout)
166+
while not _bus.queue.empty():
167+
_bus.recv(timeout=period)
168+
sleep(safe_timeout)
169+
163170
with can.ThreadSafeBus(interface="virtual", receive_own_messages=True) as bus:
164171
task = bus.send_periodic(msg, period)
165-
self.assertIsInstance(task, can.broadcastmanager.RestartableCyclicTaskABC)
172+
self.assertIsInstance(task, can.broadcastmanager.ThreadBasedCyclicSendTask)
166173

167174
# Test that the task is sending messages
168175
sleep(safe_timeout)
169176
assert not bus.queue.empty(), "messages should have been transmitted"
170177

171178
# Stop the task and check that messages are no longer being sent
172179
bus.stop_all_periodic_tasks(remove_tasks=False)
180+
_read_all_messages(bus)
181+
assert bus.queue.empty(), "messages should not have been transmitted"
182+
183+
# Restart the task and check that messages are being sent again
184+
task.start()
173185
sleep(safe_timeout)
174-
while not bus.queue.empty():
175-
bus.recv(timeout=period)
176-
sleep(safe_timeout)
186+
assert not bus.queue.empty(), "messages should have been transmitted"
187+
188+
# Stop the task and check that messages are no longer being sent
189+
bus.stop_all_periodic_tasks(remove_tasks=False)
190+
_read_all_messages(bus)
191+
assert bus.queue.empty(), "messages should not have been transmitted"
192+
193+
# Restart the task with limited duration and wait until it stops
194+
task.duration = duration
195+
task.start()
196+
sleep(duration + safe_timeout)
197+
assert task.stopped
198+
assert time.time() > task.end_time
199+
assert not bus.queue.empty(), "messages should have been transmitted"
200+
_read_all_messages(bus)
177201
assert bus.queue.empty(), "messages should not have been transmitted"
178202

179203
# Restart the task and check that messages are being sent again

0 commit comments

Comments
 (0)