Split up the updating of service status and serving requests into two threads.

This commit is contained in:
2025-08-29 21:39:04 +02:00
parent ce811eae7e
commit d7a118931b
4 changed files with 51 additions and 96 deletions

22
main.py Normal file
View File

@@ -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)

View File

@@ -1,5 +1,3 @@
# import requests as r
from flask import jsonify, Flask
from typing import Any, Optional from typing import Any, Optional
@@ -7,11 +5,11 @@ class service:
url: str url: str
status: Optional[int] status: Optional[int]
online: bool 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.url = url
self.private = private self.public = public
self.online = False self.online = False
self.status = None self.status = None
@@ -20,7 +18,7 @@ class service:
return { return {
"url": self.url, "url": self.url,
"status": self.status, "status": self.status,
"private": self.private, "public": self.public,
"online": self.online, "online": self.online,
} }
@@ -31,18 +29,5 @@ class service:
services: list[service] = [ services: list[service] = [
service("https://git.ihatemen.uk"), service("https://git.ihatemen.uk"),
service("https://plex.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)

24
poll_services.py Normal file
View File

@@ -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)

76
test.py
View File

@@ -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)