mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 11:11:49 +02:00
SIGTERM 15 demonstration
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
# pylint: disable = no-name-in-module,missing-module-docstring
|
# pylint: disable = no-name-in-module,missing-module-docstring
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
@ -266,6 +267,49 @@ CONFIG_REDIS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def list_active_threads():
|
||||||
|
num_threads = threading.enumerate()
|
||||||
|
for thread in num_threads:
|
||||||
|
print(f"Thread Name: {thread.name},(ID: {thread.ident}), Alive: {thread.is_alive()}")
|
||||||
|
print(f"Total number of threads: {len(num_threads)}")
|
||||||
|
|
||||||
|
|
||||||
|
class ThreadTracker:
|
||||||
|
def __init__(self, exclude_names=None):
|
||||||
|
self.exclude_names = exclude_names if exclude_names else []
|
||||||
|
self.initial_threads = self._capture_threads()
|
||||||
|
|
||||||
|
def _capture_threads(self):
|
||||||
|
return set(
|
||||||
|
th
|
||||||
|
for th in threading.enumerate()
|
||||||
|
if not any(ex_name in th.name for ex_name in self.exclude_names)
|
||||||
|
and th is not threading.main_thread()
|
||||||
|
)
|
||||||
|
|
||||||
|
def _thread_info(self, threads):
|
||||||
|
return ", \n".join(f"{th.name}(ID: {th.ident})" for th in threads)
|
||||||
|
|
||||||
|
def check_unfinished_threads(self):
|
||||||
|
current_threads = self._capture_threads()
|
||||||
|
additional_threads = current_threads - self.initial_threads
|
||||||
|
closed_threads = self.initial_threads - current_threads
|
||||||
|
if additional_threads:
|
||||||
|
raise Exception(
|
||||||
|
f"###### Initial threads ######:\n {self._thread_info(self.initial_threads)}\n"
|
||||||
|
f"###### Current threads ######:\n {self._thread_info(current_threads)}\n"
|
||||||
|
f"###### Closed threads ######:\n {self._thread_info(closed_threads)}\n"
|
||||||
|
f"###### Unfinished threads ######:\n {self._thread_info(additional_threads)}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
"All threads properly closed.\n"
|
||||||
|
f"###### Initial threads ######:\n {self._thread_info(self.initial_threads)}\n"
|
||||||
|
f"###### Current threads ######:\n {self._thread_info(current_threads)}\n"
|
||||||
|
f"###### Closed threads ######:\n {self._thread_info(closed_threads)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BECMonitor(pg.GraphicsLayoutWidget):
|
class BECMonitor(pg.GraphicsLayoutWidget):
|
||||||
update_signal = pyqtSignal()
|
update_signal = pyqtSignal()
|
||||||
|
|
||||||
@ -282,8 +326,8 @@ class BECMonitor(pg.GraphicsLayoutWidget):
|
|||||||
|
|
||||||
# Client and device manager from BEC
|
# Client and device manager from BEC
|
||||||
self.plot_data = None
|
self.plot_data = None
|
||||||
bec_dispatcher = BECDispatcher()
|
self.bec_dispatcher = BECDispatcher()
|
||||||
self.client = bec_dispatcher.client if client is None else client
|
self.client = self.bec_dispatcher.client if client is None else client
|
||||||
self.dev = self.client.device_manager.devices
|
self.dev = self.client.device_manager.devices
|
||||||
self.queue = self.client.queue
|
self.queue = self.client.queue
|
||||||
|
|
||||||
@ -294,12 +338,16 @@ class BECMonitor(pg.GraphicsLayoutWidget):
|
|||||||
self.gui_id = self.__class__.__name__ + str(time.time())
|
self.gui_id = self.__class__.__name__ + str(time.time())
|
||||||
|
|
||||||
# Connect slots dispatcher
|
# Connect slots dispatcher
|
||||||
bec_dispatcher.connect_slot(self.on_scan_segment, MessageEndpoints.scan_segment())
|
self.bec_dispatcher.connect_slot(self.on_scan_segment, MessageEndpoints.scan_segment())
|
||||||
bec_dispatcher.connect_slot(self.on_config_update, MessageEndpoints.gui_config(self.gui_id))
|
self.bec_dispatcher.connect_slot(
|
||||||
bec_dispatcher.connect_slot(
|
self.on_config_update, MessageEndpoints.gui_config(self.gui_id)
|
||||||
|
)
|
||||||
|
self.bec_dispatcher.connect_slot(
|
||||||
self.on_instruction, MessageEndpoints.gui_instructions(self.gui_id)
|
self.on_instruction, MessageEndpoints.gui_instructions(self.gui_id)
|
||||||
)
|
)
|
||||||
bec_dispatcher.connect_slot(self.on_data_from_redis, MessageEndpoints.gui_data(self.gui_id))
|
self.bec_dispatcher.connect_slot(
|
||||||
|
self.on_data_from_redis, MessageEndpoints.gui_data(self.gui_id)
|
||||||
|
)
|
||||||
|
|
||||||
# Current configuration
|
# Current configuration
|
||||||
self.config = config
|
self.config = config
|
||||||
@ -816,6 +864,35 @@ class BECMonitor(pg.GraphicsLayoutWidget):
|
|||||||
self.update_plot(source_type="redis")
|
self.update_plot(source_type="redis")
|
||||||
print(f"database after: {self.database}")
|
print(f"database after: {self.database}")
|
||||||
|
|
||||||
|
def closeEvent(self, event):
|
||||||
|
self.bec_dispatcher.disconnect_all()
|
||||||
|
if not hasattr(self, "thread_tracker"):
|
||||||
|
self.thread_tracker = ThreadTracker(exclude_names=["loguru"])
|
||||||
|
try:
|
||||||
|
self.thread_tracker.check_unfinished_threads()
|
||||||
|
print("Active threads at application close:")
|
||||||
|
list_active_threads()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
finally:
|
||||||
|
event.accept()
|
||||||
|
# self.bec_dispatcher.disconnect_slot(self.on_scan_segment, MessageEndpoints.scan_segment())
|
||||||
|
# self.bec_dispatcher.disconnect_slot(
|
||||||
|
# self.on_config_update, MessageEndpoints.gui_config(self.gui_id)
|
||||||
|
# )
|
||||||
|
# self.bec_dispatcher.disconnect_slot(
|
||||||
|
# self.on_instruction, MessageEndpoints.gui_instructions(self.gui_id)
|
||||||
|
# )
|
||||||
|
# self.bec_dispatcher.disconnect_slot(
|
||||||
|
# self.on_data_from_redis, MessageEndpoints.gui_data(self.gui_id)
|
||||||
|
# )
|
||||||
|
# self.bec_dispatcher.disconnect_all()
|
||||||
|
# print("dispatcher done, now waiting")
|
||||||
|
# time.sleep(1)
|
||||||
|
# print("app will close now")
|
||||||
|
#
|
||||||
|
# super().closeEvent(event)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__": # pragma: no cover
|
if __name__ == "__main__": # pragma: no cover
|
||||||
import argparse
|
import argparse
|
||||||
@ -852,4 +929,4 @@ if __name__ == "__main__": # pragma: no cover
|
|||||||
# "y": {"y_default_tag": {"data": [1, 2, 3]}},
|
# "y": {"y_default_tag": {"data": [1, 2, 3]}},
|
||||||
# }
|
# }
|
||||||
# monitor.on_data_from_redis({"data": redis_data})
|
# monitor.on_data_from_redis({"data": redis_data})
|
||||||
sys.exit(app.exec())
|
sys.exit(app.exec_())
|
||||||
|
Reference in New Issue
Block a user