feat(socket): add cache mechanism for SocketSignal

This commit is contained in:
2026-03-03 13:54:09 +01:00
parent df811c3b7b
commit c10f1401f1
+34
View File
@@ -3,6 +3,7 @@ import functools
import socket
import time
import typing
import uuid
import numpy as np
from bec_lib import bec_logger
@@ -82,8 +83,28 @@ def data_type(val):
class SocketSignal(abc.ABC, Signal):
"""
Base class for signals that interact with a socket connection. Subclasses
must implement the '_socket_get'and 'socket_set' methods to define how to
read from and write to the socket respectively. The signal also implements
an in-built caching mechanism if 'get' is called in a callback
from a subscription to avoid multiple socket reads in a recursion. It is important
that children keep the logic in 'read' and 'get' and implement the socket read logic
in '_socket_get' to ensure the caching mechanism works correctly.
Args:
name (str): The name of the signal.
readback_timeout (float): Time in seconds to wait between socket read attempts before
returning cached value.
"""
SUB_SETPOINT = "setpoint"
def __init__(self, *, name, **kwargs):
super().__init__(name=name, **kwargs)
self._active_socket_callbacks: set[str] = set()
@abc.abstractmethod
def _socket_get(self): ...
@@ -91,9 +112,22 @@ class SocketSignal(abc.ABC, Signal):
def _socket_set(self, val): ...
def get(self):
old_value = self._readback
self._readback = self._socket_get()
timestamp = time.time()
self._metadata["timestamp"] = timestamp
self._run_subs(
sub_type=self.SUB_VALUE, old_value=old_value, value=self._readback, timestamp=timestamp
)
return self._readback
def _run_subs(self, *args, sub_type, **kwargs):
if sub_type in self._active_socket_callbacks:
return
self._active_socket_callbacks.add(sub_type)
super()._run_subs(*args, sub_type=sub_type, **kwargs)
self._active_socket_callbacks.remove(sub_type)
def put(
self,
value,