fix device_db alias corner case bugs. Closes #1140

This commit is contained in:
Sebastien Bourdeauducq 2019-11-14 16:22:45 +08:00
parent 4707aef45c
commit db13747279
4 changed files with 31 additions and 28 deletions

View File

@ -72,8 +72,8 @@
"assert lda.get_attenuation() == 42\n", "assert lda.get_attenuation() == 42\n",
"\n", "\n",
"# ... or we can wire it up ourselves if you know where it is\n", "# ... or we can wire it up ourselves if you know where it is\n",
"assert ddb.get(\"lda\")[\"host\"] == \"::1\"\n", "assert ddb.get(\"lda\", resolve_alias=True)[\"host\"] == \"::1\"\n",
"assert ddb.get(\"lda\")[\"port\"] == 3253\n", "assert ddb.get(\"lda\", resolve_alias=True)[\"port\"] == 3253\n",
"\n", "\n",
"# there are different Client types tailored to different use cases:\n", "# there are different Client types tailored to different use cases:\n",
"\n", "\n",

View File

@ -142,7 +142,8 @@ def main():
common_args.init_logger_from_args(args) common_args.init_logger_from_args(args)
if args.device is None: if args.device is None:
core_addr = DeviceDB(args.device_db).get("core")["arguments"]["host"] ddb = DeviceDB(args.device_db)
core_addr = ddb.get("core", resolve_alias=True)["arguments"]["host"]
else: else:
core_addr = args.device core_addr = args.device
mgmt = CommMgmt(core_addr) mgmt = CommMgmt(core_addr)

View File

@ -25,8 +25,12 @@ class DeviceDB:
def get_device_db(self): def get_device_db(self):
return self.data.raw_view return self.data.raw_view
def get(self, key): def get(self, key, resolve_alias=False):
return self.data.raw_view[key] desc = self.data.raw_view[key]
if resolve_alias:
while isinstance(desc, str):
desc = self.data.raw_view[desc]
return desc
class DatasetDB(TaskObject): class DatasetDB(TaskObject):

View File

@ -5,7 +5,6 @@ standalone command line tools).
""" """
from operator import setitem from operator import setitem
from collections import OrderedDict
import importlib import importlib
import logging import logging
@ -60,44 +59,43 @@ class DeviceManager:
def __init__(self, ddb, virtual_devices=dict()): def __init__(self, ddb, virtual_devices=dict()):
self.ddb = ddb self.ddb = ddb
self.virtual_devices = virtual_devices self.virtual_devices = virtual_devices
self.active_devices = OrderedDict() self.active_devices = []
def get_device_db(self): def get_device_db(self):
"""Returns the full contents of the device database.""" """Returns the full contents of the device database."""
return self.ddb.get_device_db() return self.ddb.get_device_db()
def get_desc(self, name): def get_desc(self, name):
desc = self.ddb.get(name) return self.ddb.get(name, resolve_alias=True)
while isinstance(desc, str):
# alias
desc = self.ddb.get(desc)
return desc
def get(self, name): def get(self, name):
"""Get the device driver or controller client corresponding to a """Get the device driver or controller client corresponding to a
device database entry.""" device database entry."""
if name in self.virtual_devices: if name in self.virtual_devices:
return self.virtual_devices[name] return self.virtual_devices[name]
if name in self.active_devices:
return self.active_devices[name] try:
else: desc = self.get_desc(name)
try: except Exception as e:
desc = self.get_desc(name) raise DeviceError("Failed to get description of device '{}'"
except Exception as e: .format(name)) from e
raise DeviceError("Failed to get description of device '{}'"
.format(name)) from e for existing_desc, existing_dev in self.active_devices:
try: if desc == existing_desc:
dev = _create_device(desc, self) return existing_dev
except Exception as e:
raise DeviceError("Failed to create device '{}'" try:
.format(name)) from e dev = _create_device(desc, self)
self.active_devices[name] = dev except Exception as e:
return dev raise DeviceError("Failed to create device '{}'"
.format(name)) from e
self.active_devices.append((desc, dev))
return dev
def close_devices(self): def close_devices(self):
"""Closes all active devices, in the opposite order as they were """Closes all active devices, in the opposite order as they were
requested.""" requested."""
for dev in reversed(list(self.active_devices.values())): for _desc, dev in reversed(self.active_devices):
try: try:
if isinstance(dev, (Client, BestEffortClient)): if isinstance(dev, (Client, BestEffortClient)):
dev.close_rpc() dev.close_rpc()