mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-08-13 16:07:30 +00:00
Bring back cleanup thread
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from threading import Event, Thread
|
||||
|
||||
import pytz
|
||||
|
||||
from core.data_store import DATA_STORE
|
||||
|
||||
|
||||
class CleanupTimer:
|
||||
"""Provides a timed cleanup of the spot list."""
|
||||
|
||||
def __init__(self):
|
||||
"""Constructor"""
|
||||
|
||||
self._cleanup_interval = None
|
||||
self.last_cleanup_time = datetime.min.replace(tzinfo=pytz.UTC)
|
||||
self.status = "Starting"
|
||||
self._thread = None
|
||||
self._stop_event = Event()
|
||||
|
||||
def setup(self, cleanup_interval):
|
||||
self._cleanup_interval = cleanup_interval
|
||||
|
||||
def start(self):
|
||||
"""Start the cleanup timer"""
|
||||
|
||||
self._thread = Thread(target=self._run, daemon=True)
|
||||
self._thread.start()
|
||||
|
||||
def stop(self):
|
||||
"""Stop any threads and prepare for application shutdown"""
|
||||
|
||||
self._stop_event.set()
|
||||
|
||||
def _run(self):
|
||||
while not self._stop_event.wait(timeout=self._cleanup_interval):
|
||||
self._cleanup()
|
||||
|
||||
def _cleanup(self):
|
||||
"""Perform cleanup and reschedule next timer"""
|
||||
|
||||
try:
|
||||
for i in list(DATA_STORE.spots.iterkeys()):
|
||||
try:
|
||||
spot = DATA_STORE.spots[i]
|
||||
if spot.expired():
|
||||
DATA_STORE.spots.delete(i)
|
||||
except KeyError:
|
||||
# Must have already been deleted, OK with that
|
||||
pass
|
||||
for i in list(DATA_STORE.alerts.iterkeys()):
|
||||
try:
|
||||
alert = DATA_STORE.alerts[i]
|
||||
if alert.expired():
|
||||
DATA_STORE.alerts.delete(i)
|
||||
except KeyError:
|
||||
# Must have already been deleted, OK with that
|
||||
pass
|
||||
|
||||
self.status = "OK"
|
||||
self.last_cleanup_time = datetime.now(pytz.UTC)
|
||||
|
||||
except Exception:
|
||||
self.status = "Error"
|
||||
logging.exception("Exception in Cleanup thread")
|
||||
self._stop_event.wait(timeout=1)
|
||||
|
||||
|
||||
# Global object
|
||||
CLEANUP_TIMER = CleanupTimer()
|
||||
@@ -5,6 +5,7 @@ from threading import Thread, Event
|
||||
import psutil
|
||||
import pytz
|
||||
|
||||
from core.cleanup import CLEANUP_TIMER
|
||||
from core.config import SERVER_OWNER_CALLSIGN
|
||||
from core.constants import SOFTWARE_VERSION
|
||||
from core.data_providers import DATA_PROVIDERS
|
||||
@@ -88,6 +89,9 @@ class StatusReporter:
|
||||
tzinfo=pytz.UTC).timestamp() if p.last_update_time.year > 2000 else 0,
|
||||
"lookup_count": p.lookup_count},
|
||||
DATA_PROVIDERS.callsign_data_providers))
|
||||
DATA_STORE.status_data["cleanup"] = {"status": CLEANUP_TIMER.status,
|
||||
"last_ran": CLEANUP_TIMER.last_cleanup_time.replace(
|
||||
tzinfo=pytz.UTC).timestamp() if CLEANUP_TIMER.last_cleanup_time else 0}
|
||||
DATA_STORE.status_data["webserver"] = {"status": WEB_SERVER.web_server_metrics["status"],
|
||||
"last_api_access": WEB_SERVER.web_server_metrics[
|
||||
"last_api_access_time"].replace(
|
||||
|
||||
@@ -4,6 +4,7 @@ import os
|
||||
import signal
|
||||
import sys
|
||||
|
||||
from core.cleanup import CLEANUP_TIMER
|
||||
from core.config import SERVER_OWNER_CALLSIGN, LOG_LEVEL
|
||||
from core.constants import SOFTWARE_VERSION
|
||||
from core.data_providers import DATA_PROVIDERS
|
||||
@@ -22,6 +23,7 @@ def shutdown(_signum=None, _frame=None):
|
||||
logging.info("Stopping program...")
|
||||
WEB_SERVER.stop()
|
||||
DATA_PROVIDERS.stop()
|
||||
CLEANUP_TIMER.stop()
|
||||
DATA_STORE.close()
|
||||
os._exit(0)
|
||||
|
||||
@@ -47,6 +49,8 @@ if __name__ == '__main__':
|
||||
|
||||
# Set up data store
|
||||
DATA_STORE.setup()
|
||||
CLEANUP_TIMER.setup(cleanup_interval=60)
|
||||
CLEANUP_TIMER.start()
|
||||
|
||||
# Set up and start data providers
|
||||
DATA_PROVIDERS.setup()
|
||||
|
||||
@@ -18,7 +18,6 @@ info:
|
||||
### 2.0
|
||||
|
||||
* **Breaking change:** The "add spot" API has changed to enable future support for upstream submission to the spotting services associated with various SIGs. Instead of just posting the spot object itself as the JSON content of the POST, this has moved into a `spot` object within the structure. A new `handling` object alongside it contains the `submit_upstream`, `upstream_provider`, `upstream_credentials`, and `captcha_token` fields which control the server handling of the spot.
|
||||
* **Breaking change:** Removed `cleanup` from `/status` response
|
||||
* **Breaking change:** In the `/options` response, renamed `spot_sources` and `alert_sources` to `spot_providers` and `alert_providers`
|
||||
* **Breaking change:** A user's QRZ.com and HamQTH credentials are now supplied as request headers (`X-QRZ-Username`, `X-QRZ-Password`, `X-QRZ-Session-Key`, `X-HamQTH-Username`, `X-HamQTH-Password`, `X-HamQTH-Session-ID`) rather than query parameters, to keep credentials out of server logs.
|
||||
* **Breaking change:** "WAB/WAI GRID" as a location source has been renamed to just "GRID", and also applies to Tiles on the Air spots and grid references from cluster spot comments.
|
||||
@@ -1951,6 +1950,17 @@ components:
|
||||
type: integer
|
||||
description: Number of alerts currently in the system.
|
||||
example: 123
|
||||
"cleanup":
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
description: The status of the cleanup thread
|
||||
example: OK
|
||||
last_ran:
|
||||
type: number
|
||||
description: The last time the cleanup operation ran, UTC seconds since UNIX epoch.
|
||||
example: 1759579508
|
||||
"webserver":
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@@ -12,6 +12,9 @@ function loadStatus() {
|
||||
$("#web-server-last-api").text(moment.unix(jsonData["webserver"]["last_api_access"]).utc().fromNow());
|
||||
$("#web-server-last-page").text(moment.unix(jsonData["webserver"]["last_page_access"]).utc().fromNow());
|
||||
|
||||
$("#cleanup-status").text(jsonData["cleanup"]["status"]);
|
||||
$("#cleanup-last-ran").text((jsonData["cleanup"]["last_ran"] > 0) ? moment.unix(jsonData["cleanup"]["last_ran"]).utc().fromNow() : "N/A");
|
||||
|
||||
jsonData["spot_providers"].forEach(p => {
|
||||
$("#spot_providers-status-container").append(`
|
||||
<div class="row row-cols-1 row-cols-md-4 g-4 mb-4 mb-md-2">
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<script src="/static/js/add-spot.js?v=1786599927"></script>
|
||||
<script src="/static/js/add-spot.js?v=1786601235"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-add-spot").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<script src="/static/js/alerts.js?v=1786599927"></script>
|
||||
<script src="/static/js/alerts.js?v=1786601235"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-alerts").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
@@ -79,8 +79,8 @@
|
||||
|
||||
</div>
|
||||
|
||||
<script src="/static/js/spotsbandsandmap.js?v=1786599927"></script>
|
||||
<script src="/static/js/bands.js?v=1786599927"></script>
|
||||
<script src="/static/js/spotsbandsandmap.js?v=1786601235"></script>
|
||||
<script src="/static/js/bands.js?v=1786601235"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-bands").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
{% extends "skeleton.html" %}
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/css/style.css?v=1786599927" type="text/css">
|
||||
<link rel="stylesheet" href="/static/css/style.css?v=1786601235" type="text/css">
|
||||
<link href="/static/vendor/css/bootstrap-5.3.8.min.css" rel="stylesheet">
|
||||
<link href="/static/vendor/css/fontawesome-6.7.2.min.css" rel="stylesheet">
|
||||
<link href="/static/vendor/css/solid-6.7.2.min.css" rel="stylesheet">
|
||||
@@ -10,10 +10,10 @@
|
||||
<script src="/static/vendor/js/bootstrap-5.3.8.bundle.min.js"></script>
|
||||
<script src="/static/vendor/js/tinycolor2-1.6.0.min.js"></script>
|
||||
|
||||
<script src="/static/js/utils.js?v=1786599927"></script>
|
||||
<script src="/static/js/ui-ham.js?v=1786599927"></script>
|
||||
<script src="/static/js/geo.js?v=1786599927"></script>
|
||||
<script src="/static/js/common.js?v=1786599927"></script>
|
||||
<script src="/static/js/utils.js?v=1786601235"></script>
|
||||
<script src="/static/js/ui-ham.js?v=1786601235"></script>
|
||||
<script src="/static/js/geo.js?v=1786601235"></script>
|
||||
<script src="/static/js/common.js?v=1786601235"></script>
|
||||
{% end %}
|
||||
{% block body %}
|
||||
<div class="container">
|
||||
|
||||
@@ -284,7 +284,7 @@
|
||||
</div>
|
||||
|
||||
<script src="/static/vendor/js/chart-4.4.9.umd.min.js"></script>
|
||||
<script src="/static/js/conditions.js?v=1786599927"></script>
|
||||
<script src="/static/js/conditions.js?v=1786601235"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-conditions").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
+2
-2
@@ -112,8 +112,8 @@
|
||||
<script src="/static/vendor/js/leaflet-cqzones.js"></script>
|
||||
<script src="/static/vendor/js/leaflet-workedallbritainireland.js" type="module"></script>
|
||||
|
||||
<script src="/static/js/spotsbandsandmap.js?v=1786599927"></script>
|
||||
<script src="/static/js/map.js?v=1786599927"></script>
|
||||
<script src="/static/js/spotsbandsandmap.js?v=1786601235"></script>
|
||||
<script src="/static/js/map.js?v=1786601235"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-map").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
@@ -118,8 +118,8 @@
|
||||
|
||||
</div>
|
||||
|
||||
<script src="/static/js/spotsbandsandmap.js?v=1786599927"></script>
|
||||
<script src="/static/js/spots.js?v=1786599927"></script>
|
||||
<script src="/static/js/spotsbandsandmap.js?v=1786601235"></script>
|
||||
<script src="/static/js/spots.js?v=1786601235"></script>
|
||||
<script>$(document).ready(function () {
|
||||
$("#nav-link-spots").addClass("active");
|
||||
}); <!-- highlight active page in nav --></script>
|
||||
|
||||
@@ -24,6 +24,11 @@
|
||||
<div class="col">Last API call: <span id="web-server-last-api"></span></div>
|
||||
<div class="col">Last page req: <span id="web-server-last-page"></span></div>
|
||||
</div>
|
||||
<div class="row row-cols-1 row-cols-md-4 g-4 mb-2">
|
||||
<div class="col"><strong>Cleanup Service</strong></div>
|
||||
<div class="col">Status: <span id="cleanup-status"></span></div>
|
||||
<div class="col">Last ran: <span id="cleanup-last-ran"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -81,7 +86,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/status.js?v=1786599927"></script>
|
||||
<script src="/static/js/status.js?v=1786601235"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$("#nav-link-status").addClass("active");
|
||||
|
||||
Reference in New Issue
Block a user