from apt import OpProgress
from debian_bundle import deb822
+from apt_p2p_conf import config
from Hash import HashObject
apt_pkg.init()
if filename.lower() in TRACKED_FILES:
log.msg("Registering package file: "+cache_path)
self.packages[cache_path] = file_path
+ self.packages.sync()
return True
return False
if not self.packages[f].exists():
log.msg("File in packages database has been deleted: "+f)
del self.packages[f]
+ self.packages.sync()
#{ Dictionary interface details
def __getitem__(self, key): return self.packages[key]
@ivar essential_files: files that must be created for apt to work
@type cache_dir: L{twisted.python.filepath.FilePath}
@ivar cache_dir: the directory to use for storing all files
- @type unload_delay: C{int}
- @ivar unload_delay: the time to wait before unloading the apt cache
@ivar apt_config: the configuration parameters to use for apt
@type packages: L{PackageFileList}
@ivar packages: the persistent storage of tracked apt index files
@type loading: L{twisted.internet.defer.Deferred}
@ivar loading: if the cache is currently being loaded, this will be
called when it is loaded, otherwise it is None
+ @type loading_unload: C{boolean}
+ @ivar loading_unload: whether there is an unload pending on the current load
@type unload_later: L{twisted.internet.interfaces.IDelayedCall}
@ivar unload_later: the delayed call to unload the apt cache
@type indexrecords: C{dictionary}
'apt/lists/partial')
essential_files = ('apt/dpkg/status', 'apt/etc/sources.list',)
- def __init__(self, cache_dir, unload_delay):
+ def __init__(self, cache_dir):
"""Construct a new packages manager.
@param cache_dir: directory to use to store files for this mirror
"""
self.cache_dir = cache_dir
- self.unload_delay = unload_delay
self.apt_config = deepcopy(self.DEFAULT_APT_CONFIG)
# Create the necessary files and directories for apt
self.packages = PackageFileList(cache_dir)
self.loaded = False
self.loading = None
+ self.loading_unload = False
self.unload_later = None
def __del__(self):
"""Make sure the package cache is initialized and loaded."""
# Reset the pending unload call
if self.unload_later and self.unload_later.active():
- self.unload_later.reset(self.unload_delay)
+ self.unload_later.reset(config.gettime('DEFAULT', 'UNLOAD_PACKAGES_CACHE'))
else:
- self.unload_later = reactor.callLater(self.unload_delay, self.unload)
-
+ self.unload_later = reactor.callLater(config.gettime('DEFAULT', 'UNLOAD_PACKAGES_CACHE'), self.unload)
+
+ # Check if it's already loaded
+ if self.loaded:
+ return defer.succeed(True)
+
# Make sure it's not already being loaded
if self.loading is None:
log.msg('Loading the packages cache')
+ self.loading_unload = False
self.loading = threads.deferToThread(self._load)
self.loading.addCallback(self.doneLoading)
return self.loading
def doneLoading(self, loadResult):
"""Cache is loaded."""
self.loading = None
+
+ # Check for a pending unload
+ if self.loading_unload:
+ log.msg('Re-loading the packages cache')
+ self.unload()
+ self.loading_unload = False
+ self.loading = threads.deferToThread(self._load)
+ self.loading.addCallback(self.doneLoading)
+ return self.loading
+
# Must pass on the result for the next callback
return loadResult
if self.unload_later and self.unload_later.active():
self.unload_later.cancel()
self.unload_later = None
- if self.loaded:
+ if self.loading:
+ self.loading_unload = True
+ elif self.loaded:
log.msg('Unloading the packages cache')
# This should save memory
del self.cache
def setUp(self):
"""Initializes the cache with files found in the traditional apt location."""
- self.client = AptPackages(FilePath('/tmp/.apt-p2p'), 300)
+ self.client = AptPackages(FilePath('/tmp/.apt-p2p'))
# Find the largest index files that are for 'main'
self.packagesFile = os.popen('ls -Sr /var/lib/apt/lists/ | grep -E "_main_.*Packages$" | tail -n 1').read().rstrip('\n')