-
Notifications
You must be signed in to change notification settings - Fork 30
Description
I'm trying to deploy the qlever server locally, but I keep encountering a bug: no matter how I change the port number, qlever start always shows QLever server already running on ....:port.
I checked qlever-control's source code, and I seem to have found the issue:
For my curl version:
curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.16 Release-Date: 2022-01-05
The following function (I've extracted a portion, which should be in start.py and util.py) always returns QLever server already running on ...., even though I have confirmed via lsof that there is no process using that port.
import errno
import re
import secrets
import shlex
import shutil
import socket
import string
import subprocess
from datetime import date, datetime
from pathlib import Path
from typing import Any, Optional
def run_command(
cmd: str,
return_output: bool = False,
show_output: bool = False,
show_stderr: bool = False,
use_popen: bool = False,
) -> Optional[str | subprocess.Popen]:
"""
Run the given command and throw an exception if the exit code is non-zero.
If `return_output` is `True`, return what the command wrote to `stdout`.
NOTE: The `set -o pipefail` ensures that the exit code of the command is
non-zero if any part of the pipeline fails (not just the last part).
TODO: Find the executable for `bash` in `__init__.py`.
"""
subprocess_args = {
"executable": shutil.which("bash"),
"shell": True,
"text": True,
"stdout": None if show_output else subprocess.PIPE,
"stderr": None if show_stderr else subprocess.PIPE,
}
# With `Popen`, the command runs in the current shell and a process object
# is returned (which can be used, e.g., to kill the process).
if use_popen:
if return_output:
raise Exception("Cannot return output if `use_popen` is `True`")
return subprocess.Popen(f"set -o pipefail; {cmd}", **subprocess_args)
# With `run`, the command runs in a subshell and the output is captured.
result = subprocess.run(f"set -o pipefail; {cmd}", **subprocess_args)
# If the exit code is non-zero, throw an exception. If something was
# written to `stderr`, use that as the exception message. Otherwise, use a
# generic message (which is also what `subprocess.run` does with
# `check=True`).
if result.returncode != 0:
if len(result.stderr) > 0:
raise Exception(result.stderr.replace("\n", " ").strip())
else:
raise Exception(
f"Command failed with exit code {result.returncode}, "
f" nothing written to stderr"
)
# Optionally, return what was written to `stdout`.
if return_output:
return result.stdout
def is_qlever_server_alive(endpoint_url: str) -> bool:
"""
Helper function that checks if a QLever server is running on the given
endpoint. Return `True` if the server is alive, `False` otherwise.
"""
message = "from the `qlever` CLI"
curl_cmd = (
f"curl -s {endpoint_url}/ping"
f" --data-urlencode msg={shlex.quote(message)}"
)
try:
run_command(curl_cmd)
return True
except Exception:
return False
def if_alive(endpoint_url):
if is_qlever_server_alive(endpoint_url):
print(f"QLever server already running on {endpoint_url}")
print("")
print(
"To kill the existing server, use `qlever stop` "
"or `qlever start` with option "
"--kill-existing-with-same-port`"
)
# Show output of status command.
return False
if __name__ == "__main__":
if_alive('localhost:5673') #have tried different ports, reproducing the issue
Could this be caused by a curl version issue?