From 7330784dbf9ca901bae41843883bdeb1e86f9f9a Mon Sep 17 00:00:00 2001 From: Peter Odding Date: Thu, 24 Nov 2016 23:07:38 +0100 Subject: [PATCH] Enable manual garbage collection (deb-pkg-tools --garbage-collect) --- deb_pkg_tools/cache.py | 25 +++++++++++++++++-------- deb_pkg_tools/cli.py | 22 +++++++++++++++++----- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/deb_pkg_tools/cache.py b/deb_pkg_tools/cache.py index 80edb99..df1c808 100644 --- a/deb_pkg_tools/cache.py +++ b/deb_pkg_tools/cache.py @@ -1,7 +1,7 @@ # Debian packaging tools: Caching of package metadata. # # Author: Peter Odding -# Last Change: November 23, 2016 +# Last Change: November 24, 2016 # URL: https://github.com/xolox/python-deb-pkg-tools """ @@ -154,8 +154,9 @@ def collect_garbage(self, force=False, interval=60 * 60 * 24): :param force: :data:`True` to force a full garbage collection run (defaults to :data:`False` which means garbage collection is performed only once per `interval`). - :param interval: Delay garbage collection so that it's performed only - once per given interval (the number of seconds). + :param interval: The number of seconds to delay garbage collection when + `force` is :data:`False` (a number, defaults to the + equivalent of 24 hours). """ timer = Timer() num_checked = 0 @@ -167,7 +168,11 @@ def collect_garbage(self, force=False, interval=60 * 60 * 24): elif force: logger.info("Performing forced garbage collection ..") else: - # Check when garbage collection was last run. + # Check whether garbage collection is needed, the idea being that + # garbage collection can be expensive (given enough cache entries + # and/or a cold enough disk cache) so we'd rather not do it when + # it's not necessary. + logger.debug("Checking whether garbage collection is necessary ..") try: last_gc = os.path.getmtime(marker_file) except Exception: @@ -203,10 +208,14 @@ def collect_garbage(self, force=False, interval=60 * 60 * 24): # Record when garbage collection was last run. with open(marker_file, 'a') as handle: os.utime(marker_file, None) - logger.debug("Checked %s, garbage collected %s in %s.", - pluralize(num_checked, "cache entry", "cache entries"), - pluralize(num_deleted, "cache entry", "cache entries"), - timer) + status_level = logging.INFO if force else logging.DEBUG + if num_checked == 0: + logger.log(status_level, "Nothing to garbage collect (the cache is empty).") + else: + logger.log(status_level, "Checked %s, garbage collected %s in %s.", + pluralize(num_checked, "cache entry", "cache entries"), + pluralize(num_deleted, "cache entry", "cache entries"), + timer) class CacheEntry(object): diff --git a/deb_pkg_tools/cli.py b/deb_pkg_tools/cli.py index 0f726f3..102c74e 100644 --- a/deb_pkg_tools/cli.py +++ b/deb_pkg_tools/cli.py @@ -1,7 +1,7 @@ # Debian packaging tools: Command line interface # # Author: Peter Odding -# Last Change: November 23, 2016 +# Last Change: November 24, 2016 # URL: https://github.com/xolox/python-deb-pkg-tools """ @@ -15,11 +15,12 @@ -i, --inspect=FILE - Inspect the metadata in the Debian binary package archive given by FILE. + Inspect the metadata in the Debian binary package archive given by FILE + (similar to `dpkg --info'). -c, --collect=DIR - Copy the package archive(s) given as positional arguments (and all packages + Copy the package archive(s) given as positional arguments (and all package archives required by the given package archives) into the directory given by DIR. @@ -68,6 +69,15 @@ the positional arguments as an external command (usually `apt-get install') and finally deactivate the repository. + --gc, --garbage-collect + + Force removal of stale entries from the persistent (on disk) package + metadata cache. Garbage collection is performed automatically by the + deb-pkg-tools command line interface when the last garbage collection + cycle was more than 24 hours ago, so you only need to do it manually + when you want to control when it happens (for example by a daily + cron job scheduled during idle hours :-). + -y, --yes Assume the answer to interactive questions is yes. @@ -95,7 +105,7 @@ # External dependencies. import coloredlogs from humanfriendly import format_path, format_size, parse_path -from humanfriendly.text import format, pluralize +from humanfriendly.text import compact, format, pluralize from humanfriendly.prompts import prompt_for_confirmation from humanfriendly.terminal import ( HIGHLIGHT_COLOR, @@ -138,7 +148,7 @@ def main(): options, arguments = getopt.getopt(sys.argv[1:], 'i:c:C:p:s:b:u:a:d:w:yvh', [ 'inspect=', 'collect=', 'check=', 'patch=', 'set=', 'build=', 'update-repo=', 'activate-repo=', 'deactivate-repo=', 'with-repo=', - 'yes', 'verbose', 'help' + 'gc', 'garbage-collect', 'yes', 'verbose', 'help' ]) for option, value in options: if option in ('-i', '--inspect'): @@ -177,6 +187,8 @@ def main(): directory=check_directory(value), command=arguments, cache=cache)) + elif option in ('--gc', '--garbage-collect'): + actions.append(functools.partial(cache.collect_garbage, force=True)) elif option in ('-y', '--yes'): prompt = False elif option in ('-v', '--verbose'):