From d7a118931baafb339a276dc945f48e7f46f9a390 Mon Sep 17 00:00:00 2001 From: Stef Date: Fri, 29 Aug 2025 21:39:04 +0200 Subject: [PATCH] Split up the updating of service status and serving requests into two threads. --- main.py | 22 +++++++++++ test2.py => mem/__init__.py | 25 +++--------- poll_services.py | 24 ++++++++++++ test.py | 76 ------------------------------------- 4 files changed, 51 insertions(+), 96 deletions(-) create mode 100644 main.py rename test2.py => mem/__init__.py (53%) create mode 100644 poll_services.py delete mode 100644 test.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..39765ec --- /dev/null +++ b/main.py @@ -0,0 +1,22 @@ +# import requests as r +from flask import jsonify, Flask +from poll_services import update_services +from mem import services +import threading + + +# Flask app to serve status +app = Flask(__name__) + + +@app.route("/") +def status(): + return jsonify([s.to_dict() for s in services]) + + +# Only run if directly running file +if __name__ == "__main__": + threading.Thread(target=update_services, daemon=True).start() + + # Run flask app + app.run(debug=True, use_reloader=False) diff --git a/test2.py b/mem/__init__.py similarity index 53% rename from test2.py rename to mem/__init__.py index ca98abe..6475b0a 100644 --- a/test2.py +++ b/mem/__init__.py @@ -1,5 +1,3 @@ -# import requests as r -from flask import jsonify, Flask from typing import Any, Optional @@ -7,11 +5,11 @@ class service: url: str status: Optional[int] online: bool - private: bool + public: bool - def __init__(self, url: str = "", private: bool = False): + def __init__(self, url: str = "", public: bool = True): self.url = url - self.private = private + self.public = public self.online = False self.status = None @@ -20,7 +18,7 @@ class service: return { "url": self.url, "status": self.status, - "private": self.private, + "public": self.public, "online": self.online, } @@ -31,18 +29,5 @@ class service: services: list[service] = [ service("https://git.ihatemen.uk"), service("https://plex.ihatemen.uk"), - service("https://truenas.local", True), + service("https://truenas.local", False), ] - -# Flask app to serve status -app = Flask(__name__) - - -@app.route("/") -def status(): - return jsonify([s.to_dict() for s in services]) - - -# Only run if directly running file -if __name__ == "__main__": - app.run(debug=True) diff --git a/poll_services.py b/poll_services.py new file mode 100644 index 0000000..d30ad04 --- /dev/null +++ b/poll_services.py @@ -0,0 +1,24 @@ +from mem import services +import requests +import urllib3 +import time + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + + +def update_services() -> None: + print("Updating Service Status") + while True: + for s in services: + try: + r = requests.head( + url=s.url, + verify=s.public, + allow_redirects=True, + timeout=1, + ) + s.set_status(r.ok) + except requests.exceptions.RequestException as e: + print(e) + s.set_status(False) + time.sleep(3) diff --git a/test.py b/test.py deleted file mode 100644 index 0e52e77..0000000 --- a/test.py +++ /dev/null @@ -1,76 +0,0 @@ -import time -import requests -import traceback -import urllib3 -from urllib.parse import urlparse -from flask import Flask, jsonify -from concurrent.futures import ThreadPoolExecutor, as_completed -from typing import Any - -# Start background checker -import threading - -# Disable warnings for self-signed certificates -urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) - -services = [ - "https://truenas.local/", - "https://example.com/", - "https://git.ihatemen.uk/", -] - -services_status = {} - - -# Determine SSL verification based on hostname -def should_verify_ssl(url: str): - hostname = urlparse(url).hostname - return not (hostname and hostname.endswith(".local")) - - -# Function to check a single service -def check_service(url: str) -> tuple[str, dict[str, Any]]: - try: - start = time.time() - r = requests.head( - url, allow_redirects=True, timeout=5, verify=should_verify_ssl(url) - ) - latency = int((time.time() - start) * 1000) - return url, { - "status": "up" if r.ok else "down", - "latency": latency, - "error": None, - } - except requests.exceptions.RequestException as e: - return url, { - "status": "down", - "latency": None, - "error": str(e), - "trace": traceback.format_exc(), - } - - -# Background thread that checks all services in parallel -def check_services_periodically(interval: int = 5): - while True: - with ThreadPoolExecutor(max_workers=len(services)) as executor: - futures = [executor.submit(check_service, url) for url in services] - for future in as_completed(futures): - url, result = future.result() - services_status[url] = result - time.sleep(interval) - - -threading.Thread(target=check_services_periodically, daemon=True).start() - -# Flask app to serve status -app = Flask(__name__) - - -@app.route("/status") -def status(): - return jsonify(services_status) - - -if __name__ == "__main__": - app.run(debug=True)