Path: blob/master/modules/cache.py
3055 views
import json1import os2import os.path3import threading45import diskcache6import tqdm78from modules.paths import data_path, script_path910cache_filename = os.environ.get('SD_WEBUI_CACHE_FILE', os.path.join(data_path, "cache.json"))11cache_dir = os.environ.get('SD_WEBUI_CACHE_DIR', os.path.join(data_path, "cache"))12caches = {}13cache_lock = threading.Lock()141516def dump_cache():17"""old function for dumping cache to disk; does nothing since diskcache."""1819pass202122def make_cache(subsection: str) -> diskcache.Cache:23return diskcache.Cache(24os.path.join(cache_dir, subsection),25size_limit=2**32, # 4 GB, culling oldest first26disk_min_file_size=2**18, # keep up to 256KB in Sqlite27)282930def convert_old_cached_data():31try:32with open(cache_filename, "r", encoding="utf8") as file:33data = json.load(file)34except FileNotFoundError:35return36except Exception:37os.replace(cache_filename, os.path.join(script_path, "tmp", "cache.json"))38print('[ERROR] issue occurred while trying to read cache.json; old cache has been moved to tmp/cache.json')39return4041total_count = sum(len(keyvalues) for keyvalues in data.values())4243with tqdm.tqdm(total=total_count, desc="converting cache") as progress:44for subsection, keyvalues in data.items():45cache_obj = caches.get(subsection)46if cache_obj is None:47cache_obj = make_cache(subsection)48caches[subsection] = cache_obj4950for key, value in keyvalues.items():51cache_obj[key] = value52progress.update(1)535455def cache(subsection):56"""57Retrieves or initializes a cache for a specific subsection.5859Parameters:60subsection (str): The subsection identifier for the cache.6162Returns:63diskcache.Cache: The cache data for the specified subsection.64"""6566cache_obj = caches.get(subsection)67if not cache_obj:68with cache_lock:69if not os.path.exists(cache_dir) and os.path.isfile(cache_filename):70convert_old_cached_data()7172cache_obj = caches.get(subsection)73if not cache_obj:74cache_obj = make_cache(subsection)75caches[subsection] = cache_obj7677return cache_obj787980def cached_data_for_file(subsection, title, filename, func):81"""82Retrieves or generates data for a specific file, using a caching mechanism.8384Parameters:85subsection (str): The subsection of the cache to use.86title (str): The title of the data entry in the subsection of the cache.87filename (str): The path to the file to be checked for modifications.88func (callable): A function that generates the data if it is not available in the cache.8990Returns:91dict or None: The cached or generated data, or None if data generation fails.9293The `cached_data_for_file` function implements a caching mechanism for data stored in files.94It checks if the data associated with the given `title` is present in the cache and compares the95modification time of the file with the cached modification time. If the file has been modified,96the cache is considered invalid and the data is regenerated using the provided `func`.97Otherwise, the cached data is returned.9899If the data generation fails, None is returned to indicate the failure. Otherwise, the generated100or cached data is returned as a dictionary.101"""102103existing_cache = cache(subsection)104ondisk_mtime = os.path.getmtime(filename)105106entry = existing_cache.get(title)107if entry:108cached_mtime = entry.get("mtime", 0)109if ondisk_mtime > cached_mtime:110entry = None111112if not entry or 'value' not in entry:113value = func()114if value is None:115return None116117entry = {'mtime': ondisk_mtime, 'value': value}118existing_cache[title] = entry119120dump_cache()121122return entry['value']123124125