Unexpected behavior with multiple notifiers
Opened this issue · 3 comments
Describe the bug
When there is more than one active Notifier
, only one instance receives an incoming message. Which notifier gets the message seems random.
To Reproduce
# Do this first to set up two virtual can buses with bidirectional gating:
# sudo modprobe vcan
# sudo ip link add dev vcan0 type vcan
# sudo ip link add dev vcan1 type vcan
# sudo ip link set vcan0 up
# sudo ip link set vcan1 up
# sudo modprobe can-gw
# sudo cangw -A -s vcan0 -d vcan1 -e
# sudo cangw -A -s vcan1 -d vcan0 -e
import can
class NamedPrinter(can.Printer):
def __init__(self, name: str, *args, **kwargs) -> None:
self.name = name
super().__init__(*args, **kwargs)
def on_message_received(self, msg: can.Message) -> None:
print(f"Printer {self.name}")
super().on_message_received(msg)
vbus0 = can.Bus(interface="socketcan", channel="vcan0")
vbus1 = can.Bus(interface="socketcan", channel="vcan1")
not1 = can.Notifier(vbus1, [NamedPrinter("A")])
not2 = can.Notifier(vbus1, [NamedPrinter("B")])
msg = can.Message(arbitration_id=0x11, data=b"hello")
for i in range(4):
vbus0.send(msg)
# Output:
# Printer A
# Timestamp: 1730815787.280445 ID: 00000011 X Rx DL: 5 68 65 6c 6c 6f 'hello' Channel: vcan1
# Printer B
# Timestamp: 1730815787.280519 ID: 00000011 X Rx DL: 5 68 65 6c 6c 6f 'hello' Channel: vcan1
# Printer A
# Timestamp: 1730815787.280466 ID: 00000011 X Rx DL: 5 68 65 6c 6c 6f 'hello' Channel: vcan1
# Printer B
# Timestamp: 1730815787.280531 ID: 00000011 X Rx DL: 5 68 65 6c 6c 6f 'hello' Channel: vcan1
Expected behavior
I expected all notifiers to receive all incoming messages.
If multiple simultaneous notifiers on the same bus is not supported, the documentation should mention this. Ideally, a warning or error should be raised if an additional notifier is created on a bus with an already active notifier.
Additional context
OS and version: Ubuntu 20.04
Python version: 3.13.0
python-can version: 4.4.2
python-can interface/s (if applicable): socketcan
A single notifier can handle multiple bus instances and multiple listeners:
notifier = can.Notifier([vbus1, vbus2], [NamedPrinter("A"), NamedPrinter("B")])
Yes, I know, but I still find this behavior surprising. Wouldn't it make sense to make note of it in the documentation, at least?
On a related note, is there any way to clean up orphaned notifiers? For example:
notifier = can.Notifier(vbus1, [NamedPrinter("A")])
notifier = can.Notifier(vbus1, [NamedPrinter("B")])
notifier.stop()
vbus0.send(msg)
# Output:
# Printer A
# Timestamp: 1730841762.033267 ID: 00000011 X Rx DL: 5 68 65 6c 6c 6f 'hello' Channel: vcan1
Take a look at #1890