Reuse LocalStatus() folders rather than recreate instances

If we ask twice for a LocalStatusFolder via getfolder(), we would
get a newly created instance each time. This can lead to problems,
as e.g. write locks protecting files only work within the same Folder
instance. Make it so, that we cache all Folder instances that we have
asked for and hand back the existing one if we ask again for it,
rather than recreate a new instance.

Also, make getfolders() a noop for LocalStatus. We attempted to
derive the foldername from the name of the LocalStatusfile. However,
this is not really possible, as we do file name mangling
(".$" -> "dot", "/" -> ".") and there is no way to get the original folder
name from the LocalStatus file name anyway.

This commit could potentially solve the "file not found" errors, that people
have been seeing with their LocalStatusCache files. If we have 2
instances of a LocalStatusFolder pointing to the same file, our locking
system would not work.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2012-09-01 01:02:20 +02:00
parent a1dc76ae91
commit 1b54b85f20
2 changed files with 15 additions and 12 deletions

View File

@ -295,7 +295,6 @@ class SyncableAccount(Account):
# folder delimiter etc)
remoterepos.getfolders()
localrepos.getfolders()
statusrepos.getfolders()
remoterepos.sync_folder_structure(localrepos, statusrepos)
# replicate the folderstructure between REMOTE to LOCAL

View File

@ -43,8 +43,8 @@ class LocalStatusRepository(BaseRepository):
if not os.path.exists(self.root):
os.mkdir(self.root, 0o700)
# self._folders is a list of LocalStatusFolders()
self._folders = None
# self._folders is a dict of name:LocalStatusFolders()
self._folders = {}
def getsep(self):
return '.'
@ -83,19 +83,23 @@ class LocalStatusRepository(BaseRepository):
def getfolder(self, foldername):
"""Return the Folder() object for a foldername"""
return self.LocalStatusFolderClass(foldername, self)
if foldername in self._folders:
return self._folders[foldername]
folder = self.LocalStatusFolderClass(foldername, self)
self._folders[foldername] = folder
return folder
def getfolders(self):
"""Returns a list of all cached folders."""
if self._folders != None:
return self._folders
"""Returns a list of all cached folders.
self._folders = []
for folder in os.listdir(self.root):
self._folders.append(self.getfolder(folder))
return self._folders
Does nothing for this backend. We mangle the folder file names
(see getfolderfilename) so we can not derive folder names from
the file names that we have available. TODO: need to store a
list of folder names somehow?"""
pass
def forgetfolders(self):
"""Forgets the cached list of folders, if any. Useful to run
after a sync run."""
self._folders = None
self._folders = {}