forked from M-Labs/artiq
parameter database writeback
This commit is contained in:
parent
fa441eebda
commit
c11708972d
|
@ -29,11 +29,14 @@ class Parameter(_AttributeKind):
|
||||||
"""Represents a parameter for ``AutoContext`` to process.
|
"""Represents a parameter for ``AutoContext`` to process.
|
||||||
|
|
||||||
:param default: Default value of the parameter to be used if not found
|
:param default: Default value of the parameter to be used if not found
|
||||||
in database.
|
in the database.
|
||||||
|
:param write_db: Writes any modification of the parameter back to the
|
||||||
|
database.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, default=NoDefault):
|
def __init__(self, default=NoDefault, write_db=False):
|
||||||
self.default = default
|
self.default = default
|
||||||
|
self.write_db = write_db
|
||||||
|
|
||||||
|
|
||||||
class AutoContext:
|
class AutoContext:
|
||||||
|
@ -105,6 +108,10 @@ class AutoContext:
|
||||||
|
|
||||||
self.mvs = mvs
|
self.mvs = mvs
|
||||||
for k, v in kwargs.items():
|
for k, v in kwargs.items():
|
||||||
|
if hasattr(self, k):
|
||||||
|
p = getattr(self, k)
|
||||||
|
if isinstance(p, Parameter) and p.write_db:
|
||||||
|
self.mvs.register_parameter_wb(self, k)
|
||||||
setattr(self, k, v)
|
setattr(self, k, v)
|
||||||
|
|
||||||
for k in dir(self):
|
for k in dir(self):
|
||||||
|
@ -119,6 +126,8 @@ class AutoContext:
|
||||||
" and no MVS present".format(k))
|
" and no MVS present".format(k))
|
||||||
else:
|
else:
|
||||||
value = self.mvs.get_missing_value(k, v, self)
|
value = self.mvs.get_missing_value(k, v, self)
|
||||||
|
if isinstance(v, Parameter) and v.write_db:
|
||||||
|
self.mvs.register_parameter_wb(self, k)
|
||||||
setattr(self, k, value)
|
setattr(self, k, value)
|
||||||
|
|
||||||
self.build()
|
self.build()
|
||||||
|
|
|
@ -21,6 +21,8 @@ class DeviceParamSupplier:
|
||||||
self.req_device = req_device
|
self.req_device = req_device
|
||||||
self.req_parameter = req_parameter
|
self.req_parameter = req_parameter
|
||||||
self.active_devices = OrderedDict()
|
self.active_devices = OrderedDict()
|
||||||
|
# list of (requester, name)
|
||||||
|
self.parameter_wb = []
|
||||||
|
|
||||||
def get_missing_value(self, name, kind, requester):
|
def get_missing_value(self, name, kind, requester):
|
||||||
if isinstance(kind, Device):
|
if isinstance(kind, Device):
|
||||||
|
@ -56,11 +58,20 @@ class DeviceParamSupplier:
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def register_parameter_wb(self, requester, name):
|
||||||
|
self.parameter_wb.append((requester, name))
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
"""Closes all active devices, in the opposite order as they were
|
||||||
|
requested.
|
||||||
|
|
||||||
|
Do not use the same ``DeviceParamSupplier`` again after calling
|
||||||
|
this function.
|
||||||
|
|
||||||
|
"""
|
||||||
for dev in reversed(list(self.active_devices.values())):
|
for dev in reversed(list(self.active_devices.values())):
|
||||||
if hasattr(dev, "close"):
|
if hasattr(dev, "close"):
|
||||||
dev.close()
|
dev.close()
|
||||||
self.active_devices = OrderedDict()
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceParamDB:
|
class DeviceParamDB:
|
||||||
|
|
|
@ -37,36 +37,43 @@ def put_object(obj):
|
||||||
sys.__stdout__.flush()
|
sys.__stdout__.flush()
|
||||||
|
|
||||||
|
|
||||||
def req_device(name):
|
class ParentActionError(Exception):
|
||||||
put_object({"action": "req_device", "name": name})
|
pass
|
||||||
obj = get_object()
|
|
||||||
if obj["status"] == "ok":
|
|
||||||
return obj["data"]
|
|
||||||
else:
|
|
||||||
raise KeyError
|
|
||||||
|
|
||||||
|
|
||||||
def req_parameter(name):
|
def make_parent_action(action, argnames, exception=ParentActionError):
|
||||||
put_object({"action": "req_parameter", "name": name})
|
argnames = argnames.split()
|
||||||
obj = get_object()
|
def parent_action(*args):
|
||||||
if obj["status"] == "ok":
|
request = {"action": action}
|
||||||
return obj["data"]
|
for argname, arg in zip(argnames, args):
|
||||||
else:
|
request[argname] = arg
|
||||||
raise KeyError
|
put_object(request)
|
||||||
|
reply = get_object()
|
||||||
|
if reply["status"] == "ok":
|
||||||
|
return reply["data"]
|
||||||
|
else:
|
||||||
|
raise exception
|
||||||
|
return parent_action
|
||||||
|
|
||||||
|
|
||||||
|
req_device = make_parent_action("req_device", "name", KeyError)
|
||||||
|
req_parameter = make_parent_action("req_parameter", "name", KeyError)
|
||||||
|
set_parameter = make_parent_action("set_parameter", "name value")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
sys.stdout = sys.stderr
|
sys.stdout = sys.stderr
|
||||||
|
|
||||||
dps = DeviceParamSupplier(req_device, req_parameter)
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
obj = get_object()
|
obj = get_object()
|
||||||
put_object("ack")
|
put_object("ack")
|
||||||
|
|
||||||
|
dps = DeviceParamSupplier(req_device, req_parameter)
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
run(dps, **obj)
|
run(dps, **obj)
|
||||||
|
for requester, name in dps.parameter_wb:
|
||||||
|
set_parameter(name, getattr(requester, name))
|
||||||
except Exception:
|
except Exception:
|
||||||
put_object({"action": "report_completed",
|
put_object({"action": "report_completed",
|
||||||
"status": "failed",
|
"status": "failed",
|
||||||
|
|
|
@ -36,7 +36,8 @@ def main():
|
||||||
|
|
||||||
scheduler = Scheduler({
|
scheduler = Scheduler({
|
||||||
"req_device": dpdb.req_device,
|
"req_device": dpdb.req_device,
|
||||||
"req_parameter": dpdb.req_parameter
|
"req_parameter": dpdb.req_parameter,
|
||||||
|
"set_parameter": dpdb.set_parameter
|
||||||
})
|
})
|
||||||
loop.run_until_complete(scheduler.start())
|
loop.run_until_complete(scheduler.start())
|
||||||
atexit.register(lambda: loop.run_until_complete(scheduler.stop()))
|
atexit.register(lambda: loop.run_until_complete(scheduler.stop()))
|
||||||
|
|
Loading…
Reference in New Issue