29
class FileCacheEntryMetadata(dict):
30
""" Provies a dictionary interface for metadata """
31
#TODO: This is really an AtomicDict, extact it
32
def __init__(self, manager, *args, **kwargs):
33
super(FileCacheEntryMetadata, self).__init__(*args, **kwargs)
34
self.manager = manager
36
def __getitem__(self, key):
37
f = SharedFile(self.manager.entry.metadata_path)
40
except SharedFileNotFound:
43
self.update(self.manager.metadata_serializer.load(f))
44
return super(FileCacheEntryMetadata, self).__getitem__(key)
51
def __setitem__(self, key, value):
53
super(FileCacheEntryMetadata, self).__setitem__(key, value)
56
self._atomic_update({key: value}, updater)
57
except SharedFileNotFound:
58
self._atomic_write({key: value}, updater)
60
logger.debug("metadata key '%s' is now %s" % (key, value))
62
def __delitem__(self, key):
64
super(FileCacheEntryMetadata, self).__delitem__(key)
66
# no keys left, rm the metadata file
67
raise SharedFileRollbackWithDelete
69
self._atomic_update(None, updater)
70
except SharedFileNotFound:
71
raise KeyError("key '%s' not found" % key)
73
def update(self, data):
75
super(FileCacheEntryMetadata, self).update(data)
77
self._atomic_update(data, updater)
78
except SharedFileNotFound:
79
self._atomic_write(data)
81
def _atomic_write(self, data=None, update_fn=None):
82
""" Munge data dict, then write it to disk """
83
f = SharedFile(self.manager.entry.metadata_path)
86
if update_fn is not None:
88
self.manager.metadata_serializer.dump(self, f)
95
def _atomic_update(self, data=None, update_fn=None):
96
""" Read data, munge it, write it back, atomically. If the file
97
doesn't exist already, use _atomic_write()
100
f = SharedFile(self.manager.entry.metadata_path)
104
super(FileCacheEntryMetadata, self).update(
105
self.manager.metadata_serializer.load(f))
106
if update_fn is not None:
108
self.manager.metadata_serializer.dump(self, f)
109
except SharedFileRollbackWithDelete:
110
f.request_rollback(delete=True)
117
#TODO: __contains__, __len__, keys()
119
class FileCacheEntryMetadataManager(object):
120
""" Provides a means to attach metadata to a cache entry """
121
def __init__(self, entry, metadata_serializer=lib.kval):
123
entry - pointer back to cache entry
124
metadata_serializer - used to read/write metadata to file
127
self.metadata_serializer = metadata_serializer
129
def set(self, metadata):
133
f = SharedFile(self.entry.metadata_path)
136
self.metadata_serializer.dump(metadata, f)
143
logger.debug("'%s' metadata is now %s" %
144
(self.entry.key, pformat(metadata)))
147
f = SharedFile(self.entry.metadata_path)
150
except SharedFileNotFound:
151
return FileCacheEntryMetadata(self)
154
return FileCacheEntryMetadata(
155
self, self.metadata_serializer.load(f))
159
def delete(self, wait=True):
160
logger.debug("deleting metadata for '%s'" % self.entry.key)
162
SharedFile(self.entry.metadata_path).delete(wait=wait)
163
except SharedFileNotFound:
166
30
class FileCacheEntry(SharedFile):
167
31
""" Represents a cached file
182
45
path = os.path.join(self.cache.path, self.key)
184
47
super(FileCacheEntry, self).__init__(
185
path, overwrite=overwrite, wait=wait, timeout=timeout, delay=delay)
48
path, wait=wait, timeout=timeout, delay=delay)
187
50
self.metadata_path = os.path.join(self.cache.path,
188
51
".%s.metadata" % self.key)
189
self.metadata_manager = FileCacheEntryMetadataManager(self)
53
self.metadata_file_dict = SharedFileDict(
54
self.metadata_path, serializer=kval)
191
56
def delete(self, wait=True):
193
58
SharedFile.delete(self, wait=wait)
60
def _unsafe_delete(self):
61
self.metadata._unsafe_delete()
62
SharedFile._unsafe_delete(self)
195
64
def _get_metadata(self):
196
return self.metadata_manager.get()
65
return self.metadata_file_dict
197
67
def _set_metadata(self, metadata):
198
self.metadata_manager.set(metadata)
68
self.metadata_file_dict.set(metadata)
69
logger.debug("'%s' metadata is now %s" %
70
(self.key, pformat(metadata)))
199
72
def _del_metadata(self):
200
self.metadata_manager.delete()
73
logger.debug("deleting metadata for '%s'" % self.key)
74
self.metadata_file_dict.clear()
202
76
metadata = property(_get_metadata, _set_metadata, _del_metadata)
389
263
return self._check_valid(key)
391
def _make_entry(self, key, overwrite=True, wait=True, timeout=10,
393
return FileCacheEntry(self, key, overwrite=overwrite, wait=wait,
394
timeout=timeout, delay=delay)
265
def _make_entry(self, key, wait=True, timeout=10, delay=0.5):
266
return FileCacheEntry(self, key, wait=wait, timeout=timeout,
396
269
def _rmdir_path(self):
397
270
safe_rmdir(self.path)