add signal handling to libci - #14019
Conversation
There was a problem hiding this comment.
Pull Request Overview
Adds centralized signal handling to ensure proper hub disconnection on interrupts and refactors existing cleanup logic.
- Introduces
register_signal_handlersfor SIGINT/SIGTERM cleanup callbacks - Extracts hub disconnection into
close_hubs()and hooks it into signal handling - Automatically re-registers handlers after hub methods via
__getattribute__and in port operations
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| unit-tests/run-unit-tests.py | Imported register_signal_handlers, factored out hub cleanup to close_hubs(), and wired up handlers |
| unit-tests/py/rspy/signals.py | New module defining register_signal_handlers and default abort handler |
| unit-tests/py/rspy/device_hub.py | Overrides __getattribute__ to wrap hub methods, re-registering signal handlers |
| unit-tests/py/rspy/acroname.py | Added re-registration calls in enable_ports and disable_ports after sleeps |
Comments suppressed due to low confidence (2)
unit-tests/run-unit-tests.py:520
- There are no unit tests verifying that
register_signal_handlerscorrectly invokesclose_hubson SIGINT/SIGTERM. Add tests that simulate these signals and confirm resource cleanup.
register_signal_handlers(close_hubs)
unit-tests/run-unit-tests.py:499
- The function
close_hubsreferencesdevicesbut there’s no import in this scope, leading to a NameError at runtime. Consider importingdevicesat the top or withinclose_hubs.
def close_hubs():
| def __getattribute__(self, name): | ||
| attr = super().__getattribute__(name) | ||
|
|
||
| # some hubs override / clear signals, this is used to re-register them, only for methods for now | ||
| if callable(attr) and not name.startswith('__'): | ||
| def wrapper(*args, **kwargs): | ||
| result = attr(*args, **kwargs) | ||
| signals.register_signal_handlers() | ||
| return result | ||
|
|
||
| return wrapper | ||
|
|
||
| return attr # Return non-methods or special methods as-is | ||
|
|
There was a problem hiding this comment.
[nitpick] Overriding __getattribute__ to wrap all method calls can introduce performance overhead and reduce readability. Consider explicitly invoking register_signal_handlers in critical methods instead of a blanket override.
| def __getattribute__(self, name): | |
| attr = super().__getattribute__(name) | |
| # some hubs override / clear signals, this is used to re-register them, only for methods for now | |
| if callable(attr) and not name.startswith('__'): | |
| def wrapper(*args, **kwargs): | |
| result = attr(*args, **kwargs) | |
| signals.register_signal_handlers() | |
| return result | |
| return wrapper | |
| return attr # Return non-methods or special methods as-is | |
| # Removed the __getattribute__ method as it introduces performance overhead and reduces readability. |
| changed = True | ||
| # | ||
| if changed and sleep_on_change: | ||
| signals.register_signal_handlers() |
There was a problem hiding this comment.
[nitpick] Calling register_signal_handlers on every port enable/disable may incur unnecessary overhead. Consider moving handler registration to initialization rather than inside each method.
| signals.register_signal_handlers() |
Tracked on: [LRS-1260]