fix: skip run subs recursively

This commit is contained in:
2026-05-08 17:33:17 +02:00
committed by Christian Appel
parent 88dbe2776c
commit 2f1f9d99c9
2 changed files with 34 additions and 1 deletions
+14 -1
View File
@@ -209,7 +209,20 @@ class ReadOnlySignal(Signal):
self._readback = self._value = self._get_value()
else:
self._readback = np.random.rand()
self._run_subs(sub_type=self.SUB_VALUE, old_value=old_value, value=self._readback)
try:
if (
isinstance(old_value, (int, float, list)) and old_value != self._readback
): # only run subs if the value has changed
self._run_subs(sub_type=self.SUB_VALUE, old_value=old_value, value=self._readback)
else: # must be numpy
if not np.array_equal(old_value, self._readback):
self._run_subs(
sub_type=self.SUB_VALUE, old_value=old_value, value=self._readback
)
except Exception as e:
logger.info(
f"Error in comparing old_value {old_value} with new_value {self._readback}: {e}"
)
return self._readback
# pylint: disable=arguments-differ
+20
View File
@@ -76,6 +76,7 @@ class ComputedSignal(SignalRO):
self._signal_subs = []
self._compute_method = None
self._compute_method_str = None
self._active_callbacks: set[str] = set()
def _signal_callback(self, *args, **kwargs):
old_value = self._readback
@@ -172,3 +173,22 @@ class ComputedSignal(SignalRO):
return_value = self._compute_method()
self._readback = return_value if return_value is not None else self._readback
return return_value
def _run_subs(self, *args, sub_type, **kwargs):
"""
This method runs the callbacks for a given subscription type. It is overridden to ensure that
callbacks for the same subscription type can not trigger additional subscriptions of the same type.
We thereby avoid that callbacks can triggered recursively. In practice, a callback may call 'get'
or 'read' itself, but it won't trigger any recursive calls of the callbacks for the same subscription type.
Args:
sub_type (str): The subscription type for which to run the callbacks.
"""
if sub_type in self._active_callbacks:
return
try:
self._active_callbacks.add(sub_type)
super()._run_subs(*args, sub_type=sub_type, **kwargs)
finally:
if sub_type in self._active_callbacks:
self._active_callbacks.remove(sub_type)