From c11708972d9e5e6857fa5b0d009425326fb2192f Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Wed, 7 Jan 2015 17:50:05 +0800 Subject: [PATCH] parameter database writeback --- artiq/language/context.py | 13 +++++++++-- artiq/management/dpdb.py | 13 ++++++++++- artiq/management/worker_impl.py | 39 +++++++++++++++++++-------------- frontend/artiq_master.py | 3 ++- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/artiq/language/context.py b/artiq/language/context.py index 35959e067..2fcd9d0aa 100644 --- a/artiq/language/context.py +++ b/artiq/language/context.py @@ -29,11 +29,14 @@ class Parameter(_AttributeKind): """Represents a parameter for ``AutoContext`` to process. :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.write_db = write_db class AutoContext: @@ -105,6 +108,10 @@ class AutoContext: self.mvs = mvs 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) for k in dir(self): @@ -119,6 +126,8 @@ class AutoContext: " and no MVS present".format(k)) else: 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) self.build() diff --git a/artiq/management/dpdb.py b/artiq/management/dpdb.py index 8d670b1c7..9a18b262e 100644 --- a/artiq/management/dpdb.py +++ b/artiq/management/dpdb.py @@ -21,6 +21,8 @@ class DeviceParamSupplier: self.req_device = req_device self.req_parameter = req_parameter self.active_devices = OrderedDict() + # list of (requester, name) + self.parameter_wb = [] def get_missing_value(self, name, kind, requester): if isinstance(kind, Device): @@ -56,11 +58,20 @@ class DeviceParamSupplier: else: raise NotImplementedError + def register_parameter_wb(self, requester, name): + self.parameter_wb.append((requester, name)) + 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())): if hasattr(dev, "close"): dev.close() - self.active_devices = OrderedDict() class DeviceParamDB: diff --git a/artiq/management/worker_impl.py b/artiq/management/worker_impl.py index 7e1b98e12..f79e6ccbb 100644 --- a/artiq/management/worker_impl.py +++ b/artiq/management/worker_impl.py @@ -37,36 +37,43 @@ def put_object(obj): sys.__stdout__.flush() -def req_device(name): - put_object({"action": "req_device", "name": name}) - obj = get_object() - if obj["status"] == "ok": - return obj["data"] - else: - raise KeyError +class ParentActionError(Exception): + pass -def req_parameter(name): - put_object({"action": "req_parameter", "name": name}) - obj = get_object() - if obj["status"] == "ok": - return obj["data"] - else: - raise KeyError +def make_parent_action(action, argnames, exception=ParentActionError): + argnames = argnames.split() + def parent_action(*args): + request = {"action": action} + for argname, arg in zip(argnames, args): + request[argname] = arg + 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(): sys.stdout = sys.stderr - dps = DeviceParamSupplier(req_device, req_parameter) - while True: obj = get_object() put_object("ack") + dps = DeviceParamSupplier(req_device, req_parameter) try: try: run(dps, **obj) + for requester, name in dps.parameter_wb: + set_parameter(name, getattr(requester, name)) except Exception: put_object({"action": "report_completed", "status": "failed", diff --git a/frontend/artiq_master.py b/frontend/artiq_master.py index e9abe3d20..11a1041b2 100755 --- a/frontend/artiq_master.py +++ b/frontend/artiq_master.py @@ -36,7 +36,8 @@ def main(): scheduler = Scheduler({ "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()) atexit.register(lambda: loop.run_until_complete(scheduler.stop()))