Server: If-Modified-Since, block bis Änderung; Client: sofortiger Re-Poll
This commit is contained in:
45
server.py
45
server.py
@@ -8,6 +8,7 @@ import http.server
|
||||
import socketserver
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import urllib.error
|
||||
import sys
|
||||
import os
|
||||
import threading
|
||||
@@ -31,28 +32,33 @@ last_standings_fetch_time = None
|
||||
|
||||
|
||||
def fetch_pgn():
|
||||
"""Lädt die PGN-Datei von der URL als Bytes."""
|
||||
"""Lädt die PGN-Datei von der URL als Bytes.
|
||||
Nutzt If-Modified-Since – gibt (data, changed) zurück.
|
||||
changed=False bedeutet 304 Not Modified (keine neuen Daten)."""
|
||||
global last_fetch_time
|
||||
try:
|
||||
headers = {"User-Agent": "Mozilla/5.0"}
|
||||
if last_fetch_time:
|
||||
headers["modified_since"] = str(last_fetch_time)
|
||||
headers["If-Modified-Since"] = datetime.utcfromtimestamp(last_fetch_time).strftime("%a, %d %b %Y %H:%M:%S GMT")
|
||||
req = urllib.request.Request(PGN_URL, headers=headers)
|
||||
with urllib.request.urlopen(req, timeout=31) as response:
|
||||
data = response.read()
|
||||
last_fetch_time = time.time()
|
||||
return data
|
||||
return data, True
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code == 304:
|
||||
return None, False
|
||||
print(f"[{datetime.now().strftime('%H:%M:%S')}] HTTP-Fehler: {e}")
|
||||
return None, False
|
||||
except Exception as e:
|
||||
print(f"[{datetime.now().strftime('%H:%M:%S')}] Fehler beim Laden: {e}")
|
||||
return None
|
||||
return None, False
|
||||
|
||||
|
||||
def get_pgn_content_longpoll(since=0):
|
||||
"""Long-Poll: Gibt PGN-Inhalt + mtime zurück.
|
||||
Wenn Cache seit `since` unverändert ist, wird bis zu 31s gewartet."""
|
||||
deadline = time.time() + 31
|
||||
|
||||
while time.time() < deadline:
|
||||
"""Long-Poll: Blockiert, bis sich die PGN-Datei tatsächlich ändert.
|
||||
Antwortet nur bei neuen Daten, nie mit unverändertem Stand."""
|
||||
while True:
|
||||
if os.path.exists(CACHE_FILE):
|
||||
mtime = os.path.getmtime(CACHE_FILE)
|
||||
if mtime > since:
|
||||
@@ -60,28 +66,21 @@ def get_pgn_content_longpoll(since=0):
|
||||
return f.read(), mtime
|
||||
age = time.time() - mtime
|
||||
if age >= CACHE_TTL:
|
||||
content = fetch_pgn()
|
||||
if content:
|
||||
content, changed = fetch_pgn()
|
||||
if changed and content is not None:
|
||||
with open(CACHE_FILE, "wb") as f:
|
||||
f.write(content)
|
||||
new_mtime = os.path.getmtime(CACHE_FILE)
|
||||
if new_mtime > since:
|
||||
print(f"[{datetime.now().strftime('%H:%M:%S')}] PGN via Long-Poll aktualisiert ({len(content)} Bytes)")
|
||||
return content, new_mtime
|
||||
print(f"[{datetime.now().strftime('%H:%M:%S')}] PGN via Long-Poll aktualisiert ({len(content)} Bytes)")
|
||||
return content, new_mtime
|
||||
else:
|
||||
content = fetch_pgn()
|
||||
if content:
|
||||
content, changed = fetch_pgn()
|
||||
if changed and content is not None:
|
||||
with open(CACHE_FILE, "wb") as f:
|
||||
f.write(content)
|
||||
return content, os.path.getmtime(CACHE_FILE)
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
# Timeout – aktuellen Stand zurückgeben
|
||||
if os.path.exists(CACHE_FILE):
|
||||
with open(CACHE_FILE, "rb") as f:
|
||||
return f.read(), os.path.getmtime(CACHE_FILE)
|
||||
return None, 0
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
def fetch_standings():
|
||||
|
||||
Reference in New Issue
Block a user