stable-diffusion-webui
123 строки · 4.0 Кб
1import json2import os3import os.path4import threading5import time6
7from modules.paths import data_path, script_path8
9cache_filename = os.environ.get('SD_WEBUI_CACHE_FILE', os.path.join(data_path, "cache.json"))10cache_data = None11cache_lock = threading.Lock()12
13dump_cache_after = None14dump_cache_thread = None15
16
17def dump_cache():18"""19Marks cache for writing to disk. 5 seconds after no one else flags the cache for writing, it is written.
20"""
21
22global dump_cache_after23global dump_cache_thread24
25def thread_func():26global dump_cache_after27global dump_cache_thread28
29while dump_cache_after is not None and time.time() < dump_cache_after:30time.sleep(1)31
32with cache_lock:33cache_filename_tmp = cache_filename + "-"34with open(cache_filename_tmp, "w", encoding="utf8") as file:35json.dump(cache_data, file, indent=4, ensure_ascii=False)36
37os.replace(cache_filename_tmp, cache_filename)38
39dump_cache_after = None40dump_cache_thread = None41
42with cache_lock:43dump_cache_after = time.time() + 544if dump_cache_thread is None:45dump_cache_thread = threading.Thread(name='cache-writer', target=thread_func)46dump_cache_thread.start()47
48
49def cache(subsection):50"""51Retrieves or initializes a cache for a specific subsection.
52
53Parameters:
54subsection (str): The subsection identifier for the cache.
55
56Returns:
57dict: The cache data for the specified subsection.
58"""
59
60global cache_data61
62if cache_data is None:63with cache_lock:64if cache_data is None:65try:66with open(cache_filename, "r", encoding="utf8") as file:67cache_data = json.load(file)68except FileNotFoundError:69cache_data = {}70except Exception:71os.replace(cache_filename, os.path.join(script_path, "tmp", "cache.json"))72print('[ERROR] issue occurred while trying to read cache.json, move current cache to tmp/cache.json and create new cache')73cache_data = {}74
75s = cache_data.get(subsection, {})76cache_data[subsection] = s77
78return s79
80
81def cached_data_for_file(subsection, title, filename, func):82"""83Retrieves or generates data for a specific file, using a caching mechanism.
84
85Parameters:
86subsection (str): The subsection of the cache to use.
87title (str): The title of the data entry in the subsection of the cache.
88filename (str): The path to the file to be checked for modifications.
89func (callable): A function that generates the data if it is not available in the cache.
90
91Returns:
92dict or None: The cached or generated data, or None if data generation fails.
93
94The `cached_data_for_file` function implements a caching mechanism for data stored in files.
95It checks if the data associated with the given `title` is present in the cache and compares the
96modification time of the file with the cached modification time. If the file has been modified,
97the cache is considered invalid and the data is regenerated using the provided `func`.
98Otherwise, the cached data is returned.
99
100If the data generation fails, None is returned to indicate the failure. Otherwise, the generated
101or cached data is returned as a dictionary.
102"""
103
104existing_cache = cache(subsection)105ondisk_mtime = os.path.getmtime(filename)106
107entry = existing_cache.get(title)108if entry:109cached_mtime = entry.get("mtime", 0)110if ondisk_mtime > cached_mtime:111entry = None112
113if not entry or 'value' not in entry:114value = func()115if value is None:116return None117
118entry = {'mtime': ondisk_mtime, 'value': value}119existing_cache[title] = entry120
121dump_cache()122
123return entry['value']124