From c34db8ee9b22baa7bfa6a44cabbef75573b9c0a2 Mon Sep 17 00:00:00 2001 From: Hannah Bast Date: Sun, 24 Mar 2024 01:12:38 +0100 Subject: [PATCH] Add command `clear-cache` --- src/qlever/commands/cache_stats.py | 18 ++++--- src/qlever/commands/clear_cache.py | 81 ++++++++++++++++++++++++++++++ src/qlever/commands/start.py | 5 +- src/qlever/qleverfile.py | 2 +- 4 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 src/qlever/commands/clear_cache.py diff --git a/src/qlever/commands/cache_stats.py b/src/qlever/commands/cache_stats.py index 3d1ba3c0..cef9b29a 100644 --- a/src/qlever/commands/cache_stats.py +++ b/src/qlever/commands/cache_stats.py @@ -20,23 +20,27 @@ def description(self) -> str: return ("Show how much of the cache is currently being used") def should_have_qleverfile(self) -> bool: - return True + return False def relevant_qleverfile_arguments(self) -> dict[str: list[str]]: return {"server": ["host_name", "port"]} def additional_arguments(self, subparser) -> None: - subparser.add_argument("--brief", + subparser.add_argument("--server-url", + help="URL of the QLever server, default is " + "localhost:{port}") + subparser.add_argument("--detailed", action="store_true", default=False, - help="Show only how much of the cache is " - "currently being used") + help="Show detailed statistics and settings") def execute(self, args) -> bool: # Construct the two curl commands. - cache_stats_cmd = (f"curl -s {args.host_name}:{args.port} " + server_url = (args.server_url if hasattr(args, "server_url") + else f"localhost:{args.port}") + cache_stats_cmd = (f"curl -s {server_url} " f"--data-urlencode \"cmd=cache-stats\"") - cache_settings_cmd = (f"curl -s {args.host_name}:{args.port} " + cache_settings_cmd = (f"curl -s {server_url} " f"--data-urlencode \"cmd=get-settings\"") # Show them. @@ -57,7 +61,7 @@ def execute(self, args) -> bool: return False # Brief version. - if args.brief: + if not args.detailed: cache_size = cache_settings_dict["cache-max-size"] if not cache_size.endswith(" GB"): log.error(f"Cache size {cache_size} is not in GB, " diff --git a/src/qlever/commands/clear_cache.py b/src/qlever/commands/clear_cache.py new file mode 100644 index 00000000..501359ef --- /dev/null +++ b/src/qlever/commands/clear_cache.py @@ -0,0 +1,81 @@ +from __future__ import annotations + +import re +import subprocess + +from qlever.command import QleverCommand +from qlever.commands.cache_stats import CacheStatsCommand +from qlever.log import log + + +class ClearCacheCommand(QleverCommand): + """ + Class for executing the `clear-cache` command. + """ + + def __init__(self): + pass + + def description(self) -> str: + return ("Clear the query processing cache") + + def should_have_qleverfile(self) -> bool: + return True + + def relevant_qleverfile_arguments(self) -> dict[str: list[str]]: + return {"data": ["name"], + "server": ["port", "access_token"]} + + def additional_arguments(self, subparser) -> None: + subparser.add_argument("--server-url", + help="URL of the QLever server, default is " + "localhost:{port}") + subparser.add_argument("--complete", action="store_true", + default=False, + help="Clear the cache completely, including " + "the pinned queries") + + def execute(self, args) -> bool: + # Construct command line and show it. + clear_cache_cmd = "curl -s" + if args.server_url: + clear_cache_cmd += f" {args.server_url}" + else: + clear_cache_cmd += f" localhost:{args.port}" + cmd_val = "clear-cache-complete" if args.complete else "clear-cache" + clear_cache_cmd += f" --data-urlencode \"cmd={cmd_val}\"" + if args.complete: + clear_cache_cmd += (f" --data-urlencode access-token=" + f"\"{args.access_token}\"") + self.show(clear_cache_cmd, only_show=args.show) + if args.show: + return False + + # Execute the command. + try: + clear_cache_cmd += " -w \" %{http_code}\"" + result = subprocess.run(clear_cache_cmd, shell=True, + capture_output=True, text=True, + check=True).stdout + match = re.match(r"^(.*) (\d+)$", result, re.DOTALL) + if not match: + raise Exception(f"Unexpected output:\n{result}") + error_message = match.group(1).strip() + status_code = match.group(2) + if status_code != "200": + raise Exception(error_message) + message = "Cache cleared successfully" + if args.complete: + message += " (pinned and unpinned queries)" + else: + message += " (only unpinned queries)" + log.info(message) + except Exception as e: + log.error(e) + return False + + # Show cache stats. + log.info("") + args.detailed = False + CacheStatsCommand().execute(args) + return True diff --git a/src/qlever/commands/start.py b/src/qlever/commands/start.py index 449a9ff6..7e7402bd 100644 --- a/src/qlever/commands/start.py +++ b/src/qlever/commands/start.py @@ -4,10 +4,10 @@ import time from qlever.command import QleverCommand +from qlever.commands.cache_stats import CacheStatsCommand from qlever.commands.status import StatusCommand from qlever.commands.stop import StopCommand from qlever.commands.warmup import WarmupCommand -from qlever.commands.cache_stats import CacheStatsCommand from qlever.containerize import Containerize from qlever.log import log from qlever.util import is_qlever_server_alive, run_command @@ -201,7 +201,6 @@ def execute(self, args) -> bool: # Show cache stats. log.info("") - args.brief = True + args.detailed = False CacheStatsCommand().execute(args) - return True diff --git a/src/qlever/qleverfile.py b/src/qlever/qleverfile.py index 66705a53..fa02fed8 100644 --- a/src/qlever/qleverfile.py +++ b/src/qlever/qleverfile.py @@ -106,7 +106,7 @@ def arg(*args, **kwargs): help="The name of the host on which the server listens for " "requests") server_args["port"] = arg( - "--port", type=int, required=True, + "--port", type=int, help="The port on which the server listens for requests") server_args["access_token"] = arg( "--access-token", type=str, default=None,