summaryrefslogtreecommitdiff
path: root/grc/core
diff options
context:
space:
mode:
authorMarcus Müller <mmueller@gnuradio.org>2021-05-26 22:08:44 +0200
committermormj <34754695+mormj@users.noreply.github.com>2021-06-04 19:08:50 -0400
commit9d92ffbc091ce34bba6ea5624c7fe5fe130d5136 (patch)
treea79df78b6301d998d861eff73841aed8b12fa332 /grc/core
parente2f152dd4c6d6bd9b3bc5986f7c13655fd2f6a61 (diff)
GRC: cache now time-dependent, version-sensitive
Complete Cache will be discarded if current cache file * has no version info * version older than version in cacheversion.in (i.e. after an update) Cached entry will be reloaded from yaml if * missing * cached-at property smaller than modification time of yaml file (half second tolerance, due to inelegant floating point modification time handling in python) Also, a bit of debug logging. Signed-off-by: Marcus Müller <mmueller@gnuradio.org>
Diffstat (limited to 'grc/core')
-rw-r--r--grc/core/cache.py42
-rw-r--r--grc/core/platform.py2
2 files changed, 35 insertions, 9 deletions
diff --git a/grc/core/cache.py b/grc/core/cache.py
index 4b41d1494d..ab2cc4465b 100644
--- a/grc/core/cache.py
+++ b/grc/core/cache.py
@@ -7,6 +7,7 @@
import json
import logging
import os
+import time
from .io import yaml
@@ -15,9 +16,11 @@ logger = logging.getLogger(__name__)
class Cache(object):
- def __init__(self, filename):
+ def __init__(self, filename, version = None):
self.cache_file = filename
+ self.version = version
self.cache = {}
+ self._cachetime = None
self.need_cache_write = True
self._accessed_items = set()
try:
@@ -31,24 +34,41 @@ class Cache(object):
def load(self):
try:
- logger.debug("Loading block cache from: {}".format(self.cache_file))
- with open(self.cache_file, encoding='utf-8') as cache_file:
- self.cache = json.load(cache_file)
self.need_cache_write = False
+ logger.debug(f"Loading block cache from: {self.cache_file}")
+ with open(self.cache_file, encoding='utf-8') as cache_file:
+ cache = json.load(cache_file)
+ cacheversion = cache.get("version", None)
+ logger.debug(f"Cache version {cacheversion}")
+ self._cachetime = cache.get("cached-at", 0)
+ if cacheversion == self.version:
+ logger.debug("Loaded block cache")
+ self.cache = cache["cache"]
+ else:
+ logger.info(f"Outdated cache {self.cache_file} found, "
+ "will be overwritten.")
+ raise ValueError()
except (IOError, ValueError):
self.need_cache_write = True
def get_or_load(self, filename):
self._accessed_items.add(filename)
- if os.path.getmtime(filename) <= self._converter_mtime:
+ modtime = os.path.getmtime(filename)
+ if modtime <= self._converter_mtime:
try:
- return self.cache[filename]
+ cached = self.cache[filename]
+ if int(cached["cached-at"]+0.5) >= modtime:
+ return cached["data"]
+ logger.info(f"Cache for {filename} outdated, loading yaml")
except KeyError:
pass
with open(filename, encoding='utf-8') as fp:
data = yaml.safe_load(fp)
- self.cache[filename] = data
+ self.cache[filename] = {
+ "cached-at": int(time.time()),
+ "data": data
+ }
self.need_cache_write = True
return data
@@ -59,7 +79,13 @@ class Cache(object):
logger.debug('Saving %d entries to json cache', len(self.cache))
# Dumping to binary file is only supported for Python3 >= 3.6
with open(self.cache_file, 'w', encoding='utf8') as cache_file:
- cache_file.write(json.dumps(self.cache, ensure_ascii=False))
+ cache_content = {
+ "version": self.version,
+ "cached-at": self._cachetime,
+ "cache": self.cache
+ }
+ cache_file.write(
+ json.dumps(cache_content, ensure_ascii=False))
def prune(self):
for filename in (set(self.cache) - self._accessed_items):
diff --git a/grc/core/platform.py b/grc/core/platform.py
index 02cb385e57..42d5b660c7 100644
--- a/grc/core/platform.py
+++ b/grc/core/platform.py
@@ -134,7 +134,7 @@ class Platform(Element):
# converter.run()
# logging.info('XML converter done.')
- with Cache(Constants.CACHE_FILE) as cache:
+ with Cache(Constants.CACHE_FILE, version = self.config.version) as cache:
for file_path in self._iter_files_in_block_path(path):
if file_path.endswith('.block.yml'):