# Attic 服务 import pickle as pkl from heurams.services.logger import get_logger from heurams.context import config_var from pathlib import Path import atexit from heurams.services import timer from heurams.services.exceptions import WTFException logger = get_logger(__name__) def singleton(cls): instances = {} def get_instance(ident, default): key = ident if key not in instances: instances[key] = cls(ident) instances[key].patch_dict(default) return instances[key] return get_instance atticdir = Path(config_var.get()["global"]["paths"]["misc"]) / "attics" atticdir.mkdir(parents=True, exist_ok=True) @singleton class Attic: def __init__(self, ident, default: dict = {}): self.ident = ident self.ident = self.ident.replace("", str(timer.get_daystamp())) self.ident = self.ident.replace("", str(timer.get_timestamp())) if "<" in ident or ">" in ident: raise WTFException # self.ident = get_md5(self.ident) self.pklpath = atticdir / f"{self.ident}.pkl" atexit.register(self.save) self.data = default if self.pklpath.exists(): try: self.load() return except: self.pklpath.unlink(missing_ok=True) self.pklpath.touch(exist_ok=True) def patch_dict(self, dct): self.data.update({k: v for k, v in dct.items() if k not in self.data}) def save(self): with open(atticdir / f"{self.ident}.pkl", "wb") as f: pkl.dump(self.data, f) def load(self): with open(atticdir / f"{self.ident}.pkl", "rb") as f: self.data.update(dict(pkl.load(f)))