feat: cache status updates in background thread

This commit is contained in:
2026-07-10 10:13:14 +02:00
parent 2663570f68
commit e68d7f5d01
+36 -6
View File
@@ -5,6 +5,7 @@ import time
from datetime import datetime, timezone
from math import ceil
from pathlib import Path
from threading import RLock, Thread
from typing import Callable, List, Optional, Tuple
from aarecommon.config.beamline import cfg_get
@@ -66,6 +67,7 @@ from aarecommon.models.raster_grid import CompletedRasterGrid, RasterGridRequest
from aarecommon.models.rotation_scan import CompletedRotationScan, RotationScanRequest
from aarecommon.models.tell import TellPhaseEnum, TellStateModel
from aareDB import SampleEventType
from pyparsing.helpers import empty
from aare.daq import workflows
from aare.daq.aaredb import AareWrapper
@@ -290,6 +292,10 @@ class AareDAQ:
self._automation_last_sample_name = ""
self._automation_samples_in_queue = 0
self._last_mount_error_message = ""
self._status_lock = RLock()
self._status_update_thread = Thread(target=self._status_update_loop, daemon=True)
self._status_update_error: Exception | None = None
self._status_update_thread.start()
self._screenshot_service = ScreenshotService(
mlbox=self.__mlbox,
@@ -3398,8 +3404,8 @@ class AareDAQ:
poni_rot2_rad=0.0,
)
@property
def status(self) -> DAQStatusModel:
def _update_status(self):
start = time.perf_counter()
try:
# og_start = time.perf_counter()
safe_sample, tell_ok, tell_err = self._safe_sample()
@@ -3424,7 +3430,7 @@ class AareDAQ:
)
# logger.debug(f"Safe session status call took {time.perf_counter() - start:.3f}s")
# start = time.perf_counter()
status = DAQStatusModel(
_cached_status = DAQStatusModel(
state=self.state,
busy=self.busy,
geom=safe_geom,
@@ -3444,14 +3450,38 @@ class AareDAQ:
aerotech_connected=aerotech_ok,
aerotech_error=aerotech_err,
)
# logger.debug(f"Creating DAQStatusModel took {time.perf_counter() - start:.3f}s")
# logger.debug(f"returning status call took {time.perf_counter() - og_start:.3f}s")
return status
with self._status_lock:
self._cached_status = _cached_status
# logger.debug(f"returning status call took {time.perf_counter() - og_start:.3f}s")
except Exception as e:
logger.error(f"Failed to retrieve DAQ status: {e}")
raise
logger.debug(f"Updating status took {time.perf_counter() - start:.3f}s")
def _status_update_loop(self):
while True:
try:
self._update_status()
except Exception as e:
self._status_update_error = e
return
time.sleep(0.1)
@property
def status(self) -> DAQStatusModel:
if not self._status_update_thread.is_alive():
self._status_update_thread.join(timeout=0.5)
if self._status_update_error is not None:
raise self._status_update_error
else:
raise RuntimeError(
"DAQ status update thread failed with an error not returned from the update thread"
)
with self._status_lock:
return copy.deepcopy(self._cached_status)
def cancel(self):
if self.__cfg.state == BeamlineStateEnum.DataCollection:
self.__devs.aerotech.cancel()