Skip to content

Commit faa86f5

Browse files
committed
Add incremental plane updates with since filter and robust fetch error handling
1 parent 55a4983 commit faa86f5

3 files changed

Lines changed: 51 additions & 26 deletions

File tree

Source/Application/WebViewer.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,8 +1009,9 @@ const WebViewer::Route WebViewer::routes[] = {
10091009
{ std::time_t since = w->parseSinceParam(a);
10101010
return s ? s->getShipsJSONcompact(since) : std::string("{}"); }},
10111011
{"/api/planes_array.json", nullptr, "application/json",
1012-
[](WebViewer *w, ReceiverTracker *, const std::string &)
1013-
{ return w->planes.getCompactArray(); }},
1012+
[](WebViewer *w, ReceiverTracker *, const std::string &a)
1013+
{ std::time_t since = w->parseSinceParam(a);
1014+
return w->planes.getCompactArray(false, since); }},
10141015
{"/api/binmsgs.json", nullptr, "application/json",
10151016
[](WebViewer *, ReceiverTracker *s, const std::string &)
10161017
{ return s ? s->getBinaryMessagesJSON() : std::string("[]"); }},

Source/Tracking/PlaneDB.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -436,15 +436,15 @@ class PlaneDB : public StreamIn<Plane::ADSB>
436436
}
437437
}
438438

439-
std::string getCompactArray(bool include_inactive = false)
439+
std::string getCompactArray(bool include_inactive = false, std::time_t since = 0)
440440
{
441441
std::lock_guard<std::mutex> lock(mtx);
442442

443443
std::string content;
444444
JSON::Writer w(content, 4096);
445-
w.beginObject().kv("count", count).key("values").beginArray();
446-
447445
std::time_t now = std::time(nullptr);
446+
w.beginObject().kv("count", count).kv("time", (long long)now).key("values").beginArray();
447+
448448
int ptr = first;
449449

450450
while (ptr != -1)
@@ -461,14 +461,20 @@ class PlaneDB : public StreamIn<Plane::ADSB>
461461
break;
462462
}
463463

464+
// Incremental: stop once we hit planes older than `since`
465+
if (since > 0 && (std::time_t)plane.getRxTimeUnix() < since)
466+
{
467+
break;
468+
}
469+
464470
if (time_since_update <= 60 || (time_since_update <= 300 && plane.airborne == 0))
465471
{
466472
w.beginArray().val(plane.hexident)
467473
.val_unless(plane.lat, LAT_UNDEFINED).val_unless(plane.lon, LON_UNDEFINED)
468474
.val_unless(plane.altitude, ALTITUDE_UNDEFINED).val_unless(plane.speed, SPEED_UNDEFINED)
469475
.val_unless(plane.heading, HEADING_UNDEFINED).val_unless(plane.vertrate, VERT_RATE_UNDEFINED)
470476
.val_unless(plane.squawk, SQUAWK_UNDEFINED)
471-
.val(plane.callsign).val(plane.airborne).val(plane.nMessages).val((long long)time_since_update)
477+
.val(plane.callsign).val(plane.airborne).val(plane.nMessages).val((long long)plane.getRxTimeUnix())
472478
.val_unless(plane.category, CATEGORY_UNDEFINED).val_unless(plane.signalLevel, LEVEL_UNDEFINED);
473479
if (plane.country_code[0] != ' ')
474480
w.val({plane.country_code, 2});

frontend/src/script.js

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ var interval,
1313
shipsLastCleanup = 0,
1414
binaryDB = {},
1515
planesDB = {},
16+
planesSince = 0,
17+
planesTimeout = 300,
18+
planesLastCleanup = 0,
1619
fetch_binary = false,
1720
hover_feature = undefined,
1821
show_all_tracks = false,
@@ -2824,19 +2827,18 @@ async function fetchPlanes() {
28242827

28252828
let planes = {};
28262829

2827-
let response;
28282830
try {
2829-
response = await fetch("api/planes_array.json");
2831+
const response = await fetch("api/planes_array.json" + (planesSince > 0 ? "?since=" + planesSince : ""));
2832+
if (!response.ok) {
2833+
console.log("failed loading planes: HTTP " + response.status);
2834+
return false;
2835+
}
2836+
planes = await response.json();
28302837
} catch (error) {
2831-
28322838
console.log("failed loading planes: " + error);
28332839
return false;
2834-
} finally {
28352840
}
28362841

2837-
planes = await response.json();
2838-
2839-
28402842
const keys = [
28412843
"hexident",
28422844
"lat",
@@ -2861,22 +2863,38 @@ async function fetchPlanes() {
28612863
"bearing"
28622864
];
28632865

2864-
planesDB = {};
2866+
const serverTime = planes.time || 0;
2867+
const isIncremental = planesSince > 0;
28652868

2866-
planes.values.forEach((v) => {
2867-
const p = Object.fromEntries(keys.map((k, i) => [k, v[i]]));
2869+
if (!isIncremental) planesDB = {};
28682870

2869-
p.shipclass = ShippingClass.PLANE;
2871+
if (planes.values) {
2872+
planes.values.forEach((v) => {
2873+
const p = Object.fromEntries(keys.map((k, i) => [k, v[i]]));
28702874

2871-
p.validated = 1;
2872-
p.name = p.callsign || p.hexident;
2875+
p.shipclass = ShippingClass.PLANE;
2876+
p.validated = 1;
2877+
p.name = p.callsign || p.hexident;
28732878

2874-
// Store in database
2875-
const entry = {};
2876-
entry.raw = p;
2877-
planesDB[p.hexident] = entry;
2878-
});
2879+
const hex = p.hexident;
2880+
if (hex in planesDB) {
2881+
Object.assign(planesDB[hex].raw, p);
2882+
} else {
2883+
planesDB[hex] = { raw: p };
2884+
}
2885+
});
2886+
}
28792887

2888+
planesSince = serverTime;
2889+
2890+
// Periodically expire planes silently dropped by the server's activity filter.
2891+
if (isIncremental && serverTime - planesLastCleanup > planesTimeout / 2) {
2892+
for (const hex in planesDB) {
2893+
if (serverTime - planesDB[hex].raw.last_signal > planesTimeout)
2894+
delete planesDB[hex];
2895+
}
2896+
planesLastCleanup = serverTime;
2897+
}
28802898

28812899
return true;
28822900
}
@@ -4375,7 +4393,7 @@ function getTooltipContentPlane(plane) {
43754393
getFlagStyled(plane.country, "padding: 0px; margin: 0px; margin-right: 10px; margin-left: 3px; box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); font-size: 26px; opacity: 70%") +
43764394
'<div>' +
43774395
(plane.callsign || plane.hexident) + ' at ' + altitude + '/' + speed + ' kts<br>' +
4378-
'Received ' + getDeltaTimeVal(plane.last_signal) + ' ago' +
4396+
'Received ' + getDeltaTimeVal(planesSince - plane.last_signal) + ' ago' +
43794397
'</div>' +
43804398
'</div>';
43814399
}
@@ -5562,7 +5580,7 @@ function populatePlanecard() {
55625580
document.getElementById("shipcard_plane_lat").innerHTML = plane.lat ? getLatValFormat(plane) : null;
55635581
document.getElementById("shipcard_plane_lon").innerHTML = plane.lon ? getLonValFormat(plane) : null;
55645582
document.getElementById("shipcard_plane_vertrate").textContent = plane.vertrate ? `${plane.vertrate} ft/min` : "-";
5565-
document.getElementById("shipcard_plane_last_signal").textContent = getDeltaTimeVal(plane.last_signal);;
5583+
document.getElementById("shipcard_plane_last_signal").textContent = getDeltaTimeVal(planesSince - plane.last_signal);
55665584
document.getElementById("shipcard_plane_messages").textContent = plane.nMessages || "-";
55675585
document.getElementById("shipcard_plane_downlink").textContent = getStringfromMsgType(plane.message_types);
55685586
document.getElementById("shipcard_plane_TC").textContent = getStringfromMsgType(plane.message_subtypes);

0 commit comments

Comments
 (0)