You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As #574 was closed there is a specific issue with LssMaster in the current implementation:
If this library is together with another LSS master present on the physical bus, the input queue of LssMaster will be filled up with CAN messages, eventually leading to memory overload. It is only emptied when the LssMaster is actively used to send LSS commands. This is because Network creates an LssMaster instance and activates the subscription to the LSS messages.
I think the simplest solution would be not to activate the subscription callback until LssMaster.__send_command() is called. It is also draining the queue at this point:
LSS messages are usually very rare on a CANopen bus.
The library might be used as part of a commissioning or test equipment, where LSS is one of the central elements needed. Even if just listening in such a scenario, the Queue would grow perpetually, as you discovered. That's not good.
Activating the subscription after the first __send_command() does not fix the problem, but only postpones the effect. After using one LSS command as master, we would be in just the same situation, filling up with each unrelated LSS frame onwards.
A proper fix would be to store that a command has been sent and only act upon a response if there is an active command. That could be done by adding a locally scoped closure as subscriber in __send_command(), but it will be hard to guarantee that it will be unsubscribed again.
Maybe a context manager could help with a temporary subscription?
Any other LSS frames might be of interest, for example to get logged. For that case, a permanent subscription in the LssMaster is sensible, but then the callback would need to handle a message right away instead of simply piling them up.
Overall this code is not very well designed. A better pattern for managing the notification is needed. Hopefully something that's also compatible with using this method in an asyncio context?
I'm happy to postpone this issue until we have a structure for writing unified implementations that are able to work with either regular blocking or asyncio. Then we can refactor the design to something "proper".
I'll come back later to clarify what I mean by "unified implementations". I'm working on a general discussion about it. For this specific issue, the practical implications is that we don't fix this until after asyncio is in place.
I like the context manager idea for subscriptions, btw. That could be an elegant manner to handle other protocols as well.
As #574 was closed there is a specific issue with
LssMaster
in the current implementation:If this library is together with another LSS master present on the physical bus, the input queue of
LssMaster
will be filled up with CAN messages, eventually leading to memory overload. It is only emptied when theLssMaster
is actively used to send LSS commands. This is becauseNetwork
creates anLssMaster
instance and activates the subscription to the LSS messages.canopen/canopen/network.py
Lines 53 to 55 in f1a71da
canopen/canopen/lss.py
Lines 396 to 397 in f1a71da
I think the simplest solution would be not to activate the subscription callback until
LssMaster.__send_command()
is called. It is also draining the queue at this point:canopen/canopen/lss.py
Lines 377 to 379 in f1a71da
The text was updated successfully, but these errors were encountered: