mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
Carry server structural rejections into Radio diagnostics
The proxy now skips malformed upstream rows individually but counts them, capped at 10,000, in the catalog metadata and the /stations envelope (rejectedStationCount). The count never fails health policy, so an otherwise healthy generation is still accepted. The client validates the field, adds its own rejected rows after admission, and reports degraded coverage when either side skipped rows. Adds an end-to-end proxy-to-client test and aligns DATA_SOURCES.md and CURRENT-STATE.md. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
82190d531a
commit
f93982f55e
9 files changed
+159
-23
No files matched your search
@@ -2,6 +2,7 @@ import { msg } from '../../i18n/index.js';
|
||||
import {
|
||||
RADIO_DIRECTORY_STALE_MS,
|
||||
RADIO_DIRECTORY_FUTURE_SKEW_MS,
|
||||
RADIO_REJECTED_STATION_COUNT_MAX,
|
||||
} from './policy.js';
|
||||
|
||||
// Directory errors stay English in layer state and stats; the layer row and
|
||||
@@ -64,6 +65,18 @@ export function createIngestion({
|
||||
typeof body.degraded !== 'boolean'
|
||||
)
|
||||
throw new Error('Radio directory freshness metadata was malformed');
|
||||
// Rows the server skipped as structurally malformed. Older envelopes
|
||||
// omit the field; a present value must be a bounded count.
|
||||
const serverRejectedStationCount =
|
||||
body.rejectedStationCount === undefined
|
||||
? 0
|
||||
: body.rejectedStationCount;
|
||||
if (
|
||||
!Number.isSafeInteger(serverRejectedStationCount) ||
|
||||
serverRejectedStationCount < 0 ||
|
||||
serverRejectedStationCount > RADIO_REJECTED_STATION_COUNT_MAX
|
||||
)
|
||||
throw new Error('Radio directory diagnostic metadata was malformed');
|
||||
const rows = body.stations;
|
||||
const acceptedRows = rows.filter(
|
||||
parts.catalogModel.isValidRadioDirectoryStation,
|
||||
@@ -142,9 +155,12 @@ export function createIngestion({
|
||||
}
|
||||
if (!repeatingAcceptedGeneration) layerState._updatedAt = updatedAt;
|
||||
}
|
||||
// Combine server-side structural rejections with rows this client
|
||||
// refused. The count is diagnostic: it marks coverage degraded but does
|
||||
// not undo the generation admitted above.
|
||||
layerState._rejectedStationCount = Math.min(
|
||||
1000000,
|
||||
rows.length - acceptedRows.length,
|
||||
RADIO_REJECTED_STATION_COUNT_MAX,
|
||||
serverRejectedStationCount + rows.length - acceptedRows.length,
|
||||
);
|
||||
layerState._degraded =
|
||||
body.degraded || layerState._rejectedStationCount > 0;
|
||||
|
||||
@@ -24,6 +24,10 @@ export const RADIO_DIRECTORY_STALE_MS = 7 * 24 * 60 * 60 * 1000;
|
||||
|
||||
export const RADIO_DIRECTORY_FUTURE_SKEW_MS = 5 * 60 * 1000;
|
||||
|
||||
// Bound for the server's `rejectedStationCount` envelope field and the
|
||||
// combined client counter; matches server/providers/radio/constants.js.
|
||||
export const RADIO_REJECTED_STATION_COUNT_MAX = 10_000;
|
||||
|
||||
export const RADIO_UUID_RE =
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
||||
|
||||
|
||||
Reference in new issue
Block a user