diff --git a/src/calng/base_correction.py b/src/calng/base_correction.py index b451c5ee982e0c06e6c9deca340353352041cc14..e498d34a20e0e0f7b2bb6da97531f1997612ff52 100644 --- a/src/calng/base_correction.py +++ b/src/calng/base_correction.py @@ -709,8 +709,7 @@ class BaseCorrection(PythonDevice): update = self._prereconfigure_update_hash if update.has("frameFilter"): - with self._buffer_lock: - self._update_frame_filter() + self._lock_and_update_in_background(self._update_frame_filter) elif any( update.has(shape_param) for shape_param in ( @@ -721,11 +720,17 @@ class BaseCorrection(PythonDevice): "frameFilter", ) ): - with self._buffer_lock: - self._update_buffers() + self._lock_and_update_in_background(self._update_buffers) # TODO: only call this if they are changed (is cheap, though) self._update_correction_flags() + def _lock_and_update_in_background(self, method): + # TODO: securely handle errors (postReconfigure may succeed and device state not) + def runner(): + with self._buffer_lock, utils.StateContext(self, State.CHANGING): + method() + threading.Thread(target=runner, daemon=True).start() + def loadMostRecentConstants(self): self.flush_constants() self.calcat_friend.flush_constants() diff --git a/src/calng/utils.py b/src/calng/utils.py index b14e36b84675cd06a62824828b158edcd9edbdd4..c24502a8791a74aa8b2989fef0b2e0918893e7eb 100644 --- a/src/calng/utils.py +++ b/src/calng/utils.py @@ -279,6 +279,25 @@ class Stopwatch: return f"{self.name}: {self.elapsed():.3f} s" +class StateContext: + """What if device state was a stack?""" + + def __init__(self, device, new_state, revert_to=None): + self.device = device + if revert_to is None: + revert_to = device.get("state") + self.revert_to = revert_to + self.new_state = new_state + + def __enter__(self): + if self.new_state is not self.revert_to: + self.device.updateState(self.new_state) + + def __exit__(self, t, v, tb): + if self.new_state is not self.revert_to: + self.device.updateState(self.revert_to) + + class TrainRatioTracker: """Measure how many percent of recent train IDs (from contiguous set) were seen