Perf: 9 Performance-Fixes — SW by-v1072
Backend: - DB: 3 neue Indizes (forum_posts thread+user, routes user) — Forum/Routen-Queries - Caching: cache.py (TTL-Cache ohne neue Dependency) für 5 statische Listen (training_exercises, pflege_tipps, wiki_stats, wiki_gruppen, help_articles) - diary.py + breeder_photos.py: Bildverarbeitung (ffmpeg/PIL/EXIF) per run_in_executor → blockiert Event-Loop nicht mehr - scheduler.py: 11 kollidierende Jobs auf 5-Min-Intervalle gestaggert, coalesce=True - social.py: ORDER BY RANDOM() ohne LIMIT in 2 Stellen gefixt - alerts.py: Haversine-Loop bekommt SQL-Bounding-Box-Vorfilter Frontend: - sw.js: Tile-Cache mit LRU-Eviction (max 500 Einträge) - admin.js: Event-Listener-Leak — Tab-Klicks per Delegation statt N Listener - api.js: compressImage() Helper — Client-seitiges Resize auf max 2000px (HEIC/Videos/<500KB unverändert), integriert in 8 Upload-Stellen (diary, dog-profile×2, walks, poison, lost, health×2) Bump APP_VER 1071 → 1072 (sw.js, app.js, main.py, index.html)
This commit is contained in:
parent
3abf974d29
commit
c03884cb81
23 changed files with 461 additions and 120 deletions
|
|
@ -24,12 +24,19 @@ _job_log: dict = {}
|
|||
|
||||
|
||||
def start():
|
||||
# ------------------------------------------------------------------
|
||||
# Job-Staffelung in 5-Minuten-Intervallen — verhindert gleichzeitige
|
||||
# Last-Spitzen (mehrere Jobs zur selben Sekunde 08:00 Uhr).
|
||||
# coalesce=True: bei verpassten Läufen nur ein Lauf nachholen.
|
||||
# misfire_grace_time: Mindestwert 300s, höher wo Job lange dauern kann.
|
||||
# ------------------------------------------------------------------
|
||||
_scheduler.add_job(
|
||||
_job_health_reminders,
|
||||
CronTrigger(hour=8, minute=0), # täglich 08:00 Uhr
|
||||
id="health_reminders",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
_scheduler.add_job(
|
||||
_job_poison_archive,
|
||||
|
|
@ -37,6 +44,7 @@ def start():
|
|||
id="poison_archive",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
_scheduler.add_job(
|
||||
_job_weather_alert,
|
||||
|
|
@ -44,6 +52,7 @@ def start():
|
|||
id="weather_alert",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
_scheduler.add_job(
|
||||
_job_milestone_check,
|
||||
|
|
@ -51,6 +60,7 @@ def start():
|
|||
id="milestone_check",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
_scheduler.add_job(
|
||||
_job_import_events,
|
||||
|
|
@ -58,6 +68,7 @@ def start():
|
|||
id="import_events",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=7200,
|
||||
coalesce=True,
|
||||
)
|
||||
|
||||
# Einmalig beim Start (nach 10s Verzögerung) für sofortige Befüllung
|
||||
|
|
@ -68,29 +79,32 @@ def start():
|
|||
id="import_events_startup",
|
||||
replace_existing=True,
|
||||
)
|
||||
# Alle 4 Wochen Di 03:00 — Rassen aus TheDogAPI aktualisieren
|
||||
# 1. des Monats 03:00 — Rassen aus TheDogAPI aktualisieren
|
||||
_scheduler.add_job(
|
||||
_job_seed_breeds,
|
||||
CronTrigger(day=1, hour=3, minute=0), # 1. jedes Monats
|
||||
id="seed_breeds",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Alle 4 Wochen Di 04:00 — fehlende Rassen aus Wikidata ergänzen
|
||||
# 1. des Monats 04:00 — fehlende Rassen aus Wikidata ergänzen
|
||||
_scheduler.add_job(
|
||||
_job_seed_wikidata_breeds,
|
||||
CronTrigger(day=1, hour=4, minute=0), # 1. jedes Monats
|
||||
id="seed_wikidata",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Jeden Montag 09:00 — Wöchentlicher Fortschritts-Lober
|
||||
# Jeden Montag 09:05 — Wöchentlicher Fortschritts-Lober (staggered)
|
||||
_scheduler.add_job(
|
||||
_job_weekly_praise,
|
||||
CronTrigger(day_of_week='mon', hour=9, minute=0),
|
||||
CronTrigger(day_of_week='mon', hour=9, minute=5),
|
||||
id="weekly_praise",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Täglich 06:00 Uhr Status-Report per Mail
|
||||
_scheduler.add_job(
|
||||
|
|
@ -99,6 +113,7 @@ def start():
|
|||
id="status_report",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=1800,
|
||||
coalesce=True,
|
||||
)
|
||||
# Täglich 12:00 — Moderation-Overdue-Check
|
||||
_scheduler.add_job(
|
||||
|
|
@ -107,22 +122,25 @@ def start():
|
|||
id="moderation_overdue",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=1800,
|
||||
coalesce=True,
|
||||
)
|
||||
# 1. Feb / Mai / Aug / Nov 07:00 — Quartalsbericht
|
||||
# 1. Feb / Mai / Aug / Nov 07:10 — Quartalsbericht (staggered weg von 07:00)
|
||||
_scheduler.add_job(
|
||||
_job_quarterly_report,
|
||||
CronTrigger(month="2,5,8,11", day=1, hour=7, minute=0),
|
||||
CronTrigger(month="2,5,8,11", day=1, hour=7, minute=10),
|
||||
id="quarterly_report",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=7200,
|
||||
coalesce=True,
|
||||
)
|
||||
# Jeden Montag 07:00 — KI-Gesundheitsberichte (alle 2 Wochen)
|
||||
# Jeden Montag 07:05 — KI-Gesundheitsberichte (staggered weg von 07:00)
|
||||
_scheduler.add_job(
|
||||
_job_ki_health_report,
|
||||
CronTrigger(day_of_week='mon', hour=7, minute=0),
|
||||
CronTrigger(day_of_week='mon', hour=7, minute=5),
|
||||
id="ki_health_report",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Täglich 06:30 — Wiederkehrende Ausgaben anlegen
|
||||
_scheduler.add_job(
|
||||
|
|
@ -131,6 +149,7 @@ def start():
|
|||
id="recurring_expenses",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# 1. des Monats 00:05 — Hund des Monats Sieger festlegen
|
||||
_scheduler.add_job(
|
||||
|
|
@ -139,6 +158,7 @@ def start():
|
|||
id="hdm_winner",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Täglich 19:00 Uhr — Streak-Erinnerung
|
||||
_scheduler.add_job(
|
||||
|
|
@ -147,22 +167,25 @@ def start():
|
|||
id="streak_reminder",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Täglich 08:00 Uhr — Tierfutter-Rückrufe prüfen (RASFF)
|
||||
# Täglich 08:05 Uhr — Tierfutter-Rückrufe prüfen (RASFF) (staggered weg von 08:00)
|
||||
_scheduler.add_job(
|
||||
_job_recall_check,
|
||||
CronTrigger(hour=8, minute=0),
|
||||
CronTrigger(hour=8, minute=5),
|
||||
id="recall_check",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Jeden Montag 08:00 Uhr — Neue Foto-Challenge anlegen
|
||||
# Jeden Montag 08:10 Uhr — Neue Foto-Challenge anlegen (staggered weg von 08:00)
|
||||
_scheduler.add_job(
|
||||
_job_new_foto_challenge,
|
||||
CronTrigger(day_of_week='mon', hour=8, minute=0),
|
||||
CronTrigger(day_of_week='mon', hour=8, minute=10),
|
||||
id="new_foto_challenge",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Täglich 07:00 Uhr — Goldene Gassi-Stunde
|
||||
_scheduler.add_job(
|
||||
|
|
@ -171,6 +194,7 @@ def start():
|
|||
id="golden_gassi_hour",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Täglich 09:00 Uhr — Jahrestags-Erinnerungen (Tagebuch-Einträge von heute vor X Jahren)
|
||||
_scheduler.add_job(
|
||||
|
|
@ -179,6 +203,7 @@ def start():
|
|||
id="anniversary_reminders",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# 1. des Monats 10:00 — Monatlicher Rückblick per Push
|
||||
_scheduler.add_job(
|
||||
|
|
@ -187,13 +212,16 @@ def start():
|
|||
id="monthly_recap",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
# Täglich 03:15 — Abo-Ablauf prüfen (staggered weg von 03:00 poison_archive)
|
||||
_scheduler.add_job(
|
||||
_job_subscription_check,
|
||||
CronTrigger(hour=3, minute=0),
|
||||
CronTrigger(hour=3, minute=15),
|
||||
id="subscription_check",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
_scheduler.add_job(
|
||||
_job_invoice_reminder,
|
||||
|
|
@ -201,9 +229,10 @@ def start():
|
|||
id="invoice_reminder",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
coalesce=True,
|
||||
)
|
||||
_scheduler.start()
|
||||
logger.info("Scheduler gestartet — Health-Reminder 08:00, Giftköder-Archiv 03:00, Wetter-Alert 07:30, Meilenstein-Check 00:05, Event-Import So 02:00, Rassen-Seed monatlich 1. des Monats, Status-Report täglich 06:00, Moderation-Overdue 12:00, Quartalsbericht 1. Feb/Mai/Aug/Nov 07:00, Streak-Reminder 19:00, Rückruf-Check 08:00, Goldene-Gassi-Stunde 07:00, Jahrestags-Erinnerungen 09:00, Monatlicher-Rückblick 1. des Monats 10:00, Foto-Challenge Mo 08:00, Abo-Check 03:00. OSM-Cache: on-demand (kein Prewarm).")
|
||||
logger.info("Scheduler gestartet (gestaffelt) — Health-Reminder 08:00, Giftköder-Archiv 03:00, Wetter-Alert 07:30, Meilenstein-Check 00:05, Event-Import 1.+2./4./7./10. 02:00, Rassen-Seed 1. 03:00, Wikidata-Seed 1. 04:00, Status-Report 06:00, Moderation-Overdue 12:00, Quartalsbericht 1. Feb/Mai/Aug/Nov 07:10, KI-Gesundheitsbericht Mo 07:05, Streak-Reminder 19:00, Rückruf-Check 08:05, Goldene-Gassi-Stunde 07:00, Jahrestags-Erinnerungen 09:00, Monatlicher-Rückblick 1. 10:00, Foto-Challenge Mo 08:10, Weekly-Praise Mo 09:05, Abo-Check 03:15, Invoice-Reminder 08:30. OSM-Cache: on-demand (kein Prewarm).")
|
||||
|
||||
|
||||
def stop():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue