Skip to content
Snippets Groups Projects

L2SS-1650: Allow Tango threads during read/write

Open Jan David Mol requested to merge L2SS-1650-allow-threads-during-io into main
1 file
+ 23
11
Compare changes
  • Side-by-side
  • Inline
@@ -4,8 +4,9 @@
import logging
from functools import reduce
from operator import mul
from contextlib import nullcontext
from tango import AttrWriteType, AttReqType
from tango import AttrWriteType, AttReqType, AutoTangoAllowThreads, Device
from tango.server import attribute
from attribute_wrapper.attribute_io import AttributeIO
@@ -25,6 +26,7 @@ class AttributeWrapper(attribute):
datatype=None,
dims=(1,),
access=AttrWriteType.READ,
allow_threads=True,
**kwargs,
):
"""
@@ -40,6 +42,8 @@ class AttributeWrapper(attribute):
datatype: any numpy datatype
dims: dimensions of the attribute as a tuple, or (1,) for a scalar.
init_value: value
allow_threads: if True, release Tango device lock during I/O, allowing other
Tango threads to execute.
"""
# ensure the type is a numpy array.
@@ -61,6 +65,8 @@ class AttributeWrapper(attribute):
self.datatype = datatype
self.io_context = AutoTangoAllowThreads if allow_threads else nullcontext
if dims == (1,):
# scalar
# Tango defines a scalar as having dimensions (1,0), see
@@ -107,7 +113,8 @@ class AttributeWrapper(attribute):
try:
io = self.get_attribute_io(device)
return io.cached_write_function(value)
with self.io_context(device):
return io.cached_write_function(value)
except Exception as e:
raise e.__class__(
f"Could not write attribute {comms_annotation}"
@@ -126,7 +133,8 @@ class AttributeWrapper(attribute):
try:
io = self.get_attribute_io(device)
return io.cached_read_function()
with self.io_context(device):
return io.cached_read_function()
except Exception as e:
raise e.__class__(
f"Could not read attribute {comms_annotation}"
@@ -150,7 +158,8 @@ class AttributeWrapper(attribute):
try:
io = self.get_attribute_io(device)
return io.read_function()
with AutoTangoAllowThreads(device):
return io.read_function()
except Exception as e:
raise e.__class__(
f"Could not read attribute {comms_annotation}"
@@ -178,14 +187,17 @@ class AttributeWrapper(attribute):
**kwargs,
)
def get_attribute_io(self, device):
"""Returns the attribute I/O functions from device"""
def make_attribute_io(self, device: Device) -> AttributeIO:
"""Creates and returns a new AttributeIO object for a given device"""
try:
return device._attribute_wrapper_io[self]
except KeyError:
device._attribute_wrapper_io[self] = AttributeIO(device, self)
return device._attribute_wrapper_io[self]
return AttributeIO(device, self)
def get_attribute_io(self, device: Device) -> AttributeIO:
"""Returns the (cached) attribute I/O functions from device"""
return device._attribute_wrapper_io.setdefault(
self, self.make_attribute_io(device)
)
def set_comm_client(self, device, client):
"""Takes communication client with 'get_mapping' function
Loading