comparison piecrust/cache.py @ 1188:a7c43131d871

bake: Fix file write flushing problem with Python 3.8+ Writing the cache files fails in Python 3.8 because it looks like flushing behaviour has changed. We need to explicitly flush. And even then, in very rare occurrences, it looks like it can still run into racing conditions, so we do a very hacky and ugly "retry" loop when fetching cached data :(
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 15 Jun 2021 22:36:23 -0700
parents cd0345e4001e
children
comparison
equal deleted inserted replaced
1187:161cba5d031a 1188:a7c43131d871
91 return open(cache_path, mode=mode, encoding=encoding) 91 return open(cache_path, mode=mode, encoding=encoding)
92 92
93 def write(self, path, content): 93 def write(self, path, content):
94 with self.openWrite(path, mode='w', encoding='utf8') as fp: 94 with self.openWrite(path, mode='w', encoding='utf8') as fp:
95 fp.write(content) 95 fp.write(content)
96 fp.flush()
97 os.fsync(fp)
96 98
97 def openWrite(self, path, mode='w', encoding=None): 99 def openWrite(self, path, mode='w', encoding=None):
98 cache_path = self.getCachePath(path) 100 cache_path = self.getCachePath(path)
99 cache_dir = os.path.dirname(cache_path) 101 cache_dir = os.path.dirname(cache_path)
100 if not os.path.isdir(cache_dir): 102 if not os.path.isdir(cache_dir):
184 self.cache.put(key, item) 186 self.cache.put(key, item)
185 if self.fs_cache and save_to_fs: 187 if self.fs_cache and save_to_fs:
186 fs_key = _make_fs_cache_key(key) 188 fs_key = _make_fs_cache_key(key)
187 with self.fs_cache.openWrite(fs_key, mode='wb') as fp: 189 with self.fs_cache.openWrite(fs_key, mode='wb') as fp:
188 pickle.dump(item, fp, pickle.HIGHEST_PROTOCOL) 190 pickle.dump(item, fp, pickle.HIGHEST_PROTOCOL)
191 fp.flush()
192 os.fsync(fp)
189 193
190 def get(self, key, item_maker, fs_cache_time=None, save_to_fs=True): 194 def get(self, key, item_maker, fs_cache_time=None, save_to_fs=True):
191 self._last_access_hit = True 195 self._last_access_hit = True
192 item = self.cache.get(key) 196 item = self.cache.get(key)
193 if item is not None: 197 if item is not None:
219 223
220 # Save to the file-system if needed. 224 # Save to the file-system if needed.
221 if self.fs_cache is not None and save_to_fs: 225 if self.fs_cache is not None and save_to_fs:
222 with self.fs_cache.openWrite(fs_key, mode='wb') as fp: 226 with self.fs_cache.openWrite(fs_key, mode='wb') as fp:
223 pickle.dump(item, fp, pickle.HIGHEST_PROTOCOL) 227 pickle.dump(item, fp, pickle.HIGHEST_PROTOCOL)
228 fp.flush()
229 os.fsync(fp)
224 230
225 return item 231 return item
226 232