mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-03-15 20:34:31 +00:00
Compare commits
2 Commits
61fc0b9d0f
...
2fead92dc5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fead92dc5 | ||
|
|
e8ca488001 |
@@ -10,6 +10,9 @@ import tornado_eventsource.handler
|
|||||||
from core.prometheus_metrics_handler import api_requests_counter
|
from core.prometheus_metrics_handler import api_requests_counter
|
||||||
from core.utils import serialize_everything
|
from core.utils import serialize_everything
|
||||||
|
|
||||||
|
SSE_HANDLER_MAX_QUEUE_SIZE = 100
|
||||||
|
SSE_HANDLER_QUEUE_CHECK_INTERVAL = 5000
|
||||||
|
|
||||||
|
|
||||||
# API request handler for /api/v1/alerts
|
# API request handler for /api/v1/alerts
|
||||||
class APIAlertsHandler(tornado.web.RequestHandler):
|
class APIAlertsHandler(tornado.web.RequestHandler):
|
||||||
@@ -63,11 +66,11 @@ class APIAlertsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
|||||||
self.query_params = {k: v[0].decode("utf-8") for k, v in self.request.arguments.items()}
|
self.query_params = {k: v[0].decode("utf-8") for k, v in self.request.arguments.items()}
|
||||||
|
|
||||||
# Create a alert queue and add it to the web server's list. The web server will fill this when alerts arrive
|
# Create a alert queue and add it to the web server's list. The web server will fill this when alerts arrive
|
||||||
self.alert_queue = Queue(maxsize=100)
|
self.alert_queue = Queue(maxsize=SSE_HANDLER_MAX_QUEUE_SIZE)
|
||||||
self.sse_alert_queues.append(self.alert_queue)
|
self.sse_alert_queues.append(self.alert_queue)
|
||||||
|
|
||||||
# Set up a timed callback to check if anything is in the queue
|
# Set up a timed callback to check if anything is in the queue
|
||||||
self.heartbeat = tornado.ioloop.PeriodicCallback(self._callback, 1000)
|
self.heartbeat = tornado.ioloop.PeriodicCallback(self._callback, SSE_HANDLER_QUEUE_CHECK_INTERVAL)
|
||||||
self.heartbeat.start()
|
self.heartbeat.start()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import tornado_eventsource.handler
|
|||||||
from core.prometheus_metrics_handler import api_requests_counter
|
from core.prometheus_metrics_handler import api_requests_counter
|
||||||
from core.utils import serialize_everything
|
from core.utils import serialize_everything
|
||||||
|
|
||||||
|
SSE_HANDLER_MAX_QUEUE_SIZE = 1000
|
||||||
|
SSE_HANDLER_QUEUE_CHECK_INTERVAL = 5000
|
||||||
|
|
||||||
|
|
||||||
# API request handler for /api/v1/spots
|
# API request handler for /api/v1/spots
|
||||||
class APISpotsHandler(tornado.web.RequestHandler):
|
class APISpotsHandler(tornado.web.RequestHandler):
|
||||||
@@ -65,11 +68,11 @@ class APISpotsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
|||||||
self.query_params = {k: v[0].decode("utf-8") for k, v in self.request.arguments.items()}
|
self.query_params = {k: v[0].decode("utf-8") for k, v in self.request.arguments.items()}
|
||||||
|
|
||||||
# Create a spot queue and add it to the web server's list. The web server will fill this when spots arrive
|
# Create a spot queue and add it to the web server's list. The web server will fill this when spots arrive
|
||||||
self.spot_queue = Queue(maxsize=1000)
|
self.spot_queue = Queue(maxsize=SSE_HANDLER_MAX_QUEUE_SIZE)
|
||||||
self.sse_spot_queues.append(self.spot_queue)
|
self.sse_spot_queues.append(self.spot_queue)
|
||||||
|
|
||||||
# Set up a timed callback to check if anything is in the queue
|
# Set up a timed callback to check if anything is in the queue
|
||||||
self.heartbeat = tornado.ioloop.PeriodicCallback(self._callback, 1000)
|
self.heartbeat = tornado.ioloop.PeriodicCallback(self._callback, SSE_HANDLER_QUEUE_CHECK_INTERVAL)
|
||||||
self.heartbeat.start()
|
self.heartbeat.start()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<div id="settingsButtonRow" class="row">
|
<div id="settingsButtonRow" class="row">
|
||||||
<div class="col-lg-6 me-auto pt-3">
|
<div class="col-lg-6 me-auto pt-3 hideonmobile">
|
||||||
<p id="timing-container">Loading...</p>
|
<p id="timing-container">Loading...</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 text-end">
|
<div class="col-lg-6 text-end">
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<input type="radio" class="btn-check" name="runPause" id="pauseButton" autocomplete="off">
|
<input type="radio" class="btn-check" name="runPause" id="pauseButton" autocomplete="off">
|
||||||
<label class="btn btn-outline-primary" for="pauseButton"><i class="fa-solid fa-pause"></i> Pause</label>
|
<label class="btn btn-outline-primary" for="pauseButton"><i class="fa-solid fa-pause"></i> Pause</label>
|
||||||
</span>
|
</span>
|
||||||
<span style="position: relative;">
|
<span class="hideonmobile" style="position: relative;">
|
||||||
<i id="searchicon" class="fa-solid fa-magnifying-glass"></i>
|
<i id="searchicon" class="fa-solid fa-magnifying-glass"></i>
|
||||||
<input id="search" type="search" class="form-control" oninput="filtersUpdated();" placeholder="Search">
|
<input id="search" type="search" class="form-control" oninput="filtersUpdated();" placeholder="Search">
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -345,13 +345,6 @@ div.band-spot:hover span.band-spot-info {
|
|||||||
max-height: 26em;
|
max-height: 26em;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
/* No search on mobile */
|
|
||||||
input#search {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
i#searchicon {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 992px) {
|
@media (min-width: 992px) {
|
||||||
|
|||||||
@@ -19,8 +19,11 @@ function loadSpots() {
|
|||||||
spots = jsonData;
|
spots = jsonData;
|
||||||
// Update table
|
// Update table
|
||||||
updateTable();
|
updateTable();
|
||||||
// Start SSE connection to fetch updates in the background
|
// Start SSE connection to fetch updates in the background, if we are in "run" mode
|
||||||
|
let run = $('#runButton:checked').val();
|
||||||
|
if (run) {
|
||||||
startSSEConnection();
|
startSSEConnection();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,8 +73,8 @@ function startSSEConnection() {
|
|||||||
|
|
||||||
// Update the special timing display for the live spots page, which varies depending on run/pause selection.
|
// Update the special timing display for the live spots page, which varies depending on run/pause selection.
|
||||||
function updateTimingDisplayRunPause() {
|
function updateTimingDisplayRunPause() {
|
||||||
// todo run/pause
|
let run = $('#runButton:checked').val();
|
||||||
$("#timing-container").html("Last spot received at " + lastUpdateTime.format('HH:mm') + " UTC.");
|
$("#timing-container").html((run ? "Connected to server. Last update at " : "Paused at ") + lastUpdateTime.format('HH:mm') + " UTC.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a query string for the API, based on the filters that the user has selected.
|
// Build a query string for the API, based on the filters that the user has selected.
|
||||||
@@ -474,4 +477,19 @@ $(document).ready(function() {
|
|||||||
loadOptions();
|
loadOptions();
|
||||||
// Display intro box
|
// Display intro box
|
||||||
displayIntroBox();
|
displayIntroBox();
|
||||||
|
|
||||||
|
// Set up run/pause toggles
|
||||||
|
$("#runButton").change(function() {
|
||||||
|
// Need to start the SSE connection but also do a full re-query to catch up anything that we missed, so we
|
||||||
|
// might as well just call loadSpots again which will trigger it all
|
||||||
|
loadSpots();
|
||||||
|
updateTimingDisplayRunPause();
|
||||||
|
});
|
||||||
|
$("#pauseButton").change(function() {
|
||||||
|
// If we are pausing and have an open SSE connection, stop it
|
||||||
|
if (evtSource != null) {
|
||||||
|
evtSource.close();
|
||||||
|
}
|
||||||
|
updateTimingDisplayRunPause();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user