Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor the stop command #71

Merged
merged 7 commits into from
Dec 24, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 36 additions & 26 deletions src/qlever/commands/stop.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
from __future__ import annotations

import re

import psutil

from qlever.command import QleverCommand
from qlever.commands.status import StatusCommand
from qlever.containerize import Containerize
from qlever.log import log
from qlever.util import show_process_info

# try to kill the given process, return true iff it was killed successfully.
# the process_info is used for logging.
def stop_process(proc, pinfo):
try:
proc.kill()
log.info(f"Killed process {pinfo['pid']}")
return True
except Exception as e:
log.error(f"Could not kill process with PID "
f"{pinfo['pid']} ({e}) ... try to kill it "
f"manually")
log.info("")
show_process_info(proc, "", show_heading=True)
return False


# try to stop and remove container. return True iff it was stopped
# successfully. Gives log info accordingly.
def stop_container(server_container):
for container_system in Containerize.supported_systems():
if Containerize.stop_and_remove_container(
container_system, server_container):
log.info(f"{container_system.capitalize()} container with "
f"name \"{server_container}\" stopped "
f" and removed")
return True
joka921 marked this conversation as resolved.
Show resolved Hide resolved
return False


class StopCommand(QleverCommand):
"""
Expand All @@ -20,7 +45,7 @@ def __init__(self):
pass

def description(self) -> str:
return ("Stop QLever server for a given datasedataset or port")
return "Stop QLever server for a given datasedataset or port"

def should_have_qleverfile(self) -> bool:
return True
Expand Down Expand Up @@ -54,46 +79,31 @@ def execute(self, args) -> bool:
# First check if there is container running and if yes, stop and remove
# it (unless the user has specified `--no-containers`).
if not args.no_containers:
for container_system in Containerize.supported_systems():
if Containerize.stop_and_remove_container(
container_system, args.server_container):
log.info(f"{container_system.capitalize()} container with "
f"name \"{args.server_container}\" stopped "
f" and removed")
return True
if stop_container(args.server_container):
return True

# Check if there is a process running on the server port using psutil.
#
# NOTE: On MacOS, some of the proc's returned by psutil.process_iter()
# no longer exist when we try to access them, so we just skip them.
for proc in psutil.process_iter():
try:
pinfo = proc.as_dict(
attrs=['pid', 'username', 'create_time',
'memory_info', 'cmdline'])
attrs=['pid', 'username', 'create_time',
'memory_info', 'cmdline'])
cmdline = " ".join(pinfo['cmdline'])
except Exception as e:
log.debug(f"Error getting process info: {e}")
return False
if re.search(cmdline_regex, cmdline):
log.info(f"Found process {pinfo['pid']} from user "
f"{pinfo['username']} with command line: {cmdline}")
log.info("")
try:
proc.kill()
log.info(f"Killed process {pinfo['pid']}")
except Exception as e:
log.error(f"Could not kill process with PID "
f"{pinfo['pid']} ({e}) ... try to kill it "
f"manually")
log.info("")
show_process_info(proc, "", show_heading=True)
return False
return True
return stop_process(proc, pinfo)

# If no matching process found, show a message and the output of the
# status command.
message = "No matching process found" if args.no_containers else \
"No matching process or container found"
"No matching process or container found"
log.error(message)
args.cmdline_regex = "^ServerMain.* -i [^ ]*"
log.info("")
Expand Down
Loading