From 9e1f2068bb12eb5570dbdfb8da413f3c9632f2e7 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver <thomas@kluyver.me.uk> Date: Mon, 19 Dec 2022 17:16:16 +0000 Subject: [PATCH] Add function to update metadata.yml with file locking --- src/cal_tools/tools.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/cal_tools/tools.py b/src/cal_tools/tools.py index 2d15866ac..ee54ffa82 100644 --- a/src/cal_tools/tools.py +++ b/src/cal_tools/tools.py @@ -4,6 +4,7 @@ import os import re import zlib from collections import OrderedDict +from fcntl import lockf, LOCK_EX, LOCK_UN from glob import glob from multiprocessing.pool import ThreadPool from os import environ, listdir, path @@ -811,6 +812,35 @@ def module_index_to_qm(index: int, total_modules: int = 16): return f"Q{quad+1}M{mod+1}" +def recursive_update(target: dict, source: dict): + for k, v2 in source.items(): + v1 = target.get(k, None) + if isinstance(v1, dict) and isinstance(v2, dict): + recursive_update(v1, v2) + else: + target[k] = v2 + + +def update_metadata(folder, changes: dict): + yaml_fn = Path(folder) / "calibration_metadata.yml" + try: + f = yaml_fn.open('x') + except FileExistsError: + f = yaml_fn.open('r+') + + with f: + lockf(f, LOCK_EX) + d = yaml.safe_load(f) + if d is None: + d = {} + + recursive_update(d, changes) + + f.seek(0) + yaml.safe_dump(d, f) + f.truncate() + + class CalibrationMetadata(dict): """Convenience class: dictionary stored in metadata YAML file -- GitLab