mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
fix(overpass): keep proxied traffic out of the direct-loopback admission reserve; keep a measured arrival-angle failure through a reveal timeout
- /api/overpass: a loopback socket with forwarding headers (a local reverse proxy) is admitted from the remote pool under a socket-keyed proxied: bucket, never the owner's direct-loopback window; the upstream limiter uses the same key. Regression: owner cache hits survive an exhausted proxy bucket. - Arrival check: a reveal timeout keeps the settle angle it measured; the new observeArrivalRotationWithRetry retries only inconclusive timeouts, so a real violation cannot be retried into a pass. Regression: wrong settle angle -> reveal timeout -> clean second attempt still fails. - SECURITY.md, README, changelog and CURRENT-STATE: scope the guarantee to admission isolation, name the forwarding headers a local proxy must send, and state that the upstream budget stays shared.
This commit is contained in:
1 parent
7a421c35fc
commit
8f16d10f7a
9 files changed
+295
-67
No files matched your search
@@ -2,18 +2,20 @@ import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import {
|
||||
ARRIVAL_OBSERVATION_MS,
|
||||
arrivalAngleViolated,
|
||||
arrivalRotationPassed,
|
||||
observeArrivalRotation,
|
||||
observeArrivalRotationWithRetry,
|
||||
} from './trackArrivalObservation.mjs';
|
||||
|
||||
function fixture() {
|
||||
function fixture(start = observeArrivalRotation) {
|
||||
let time = 0;
|
||||
let state = { shown: true, rotationError: 0 };
|
||||
const listeners = new Set();
|
||||
const timers = new Map();
|
||||
let renders = 0;
|
||||
let moveEnds = 0;
|
||||
const observation = observeArrivalRotation({
|
||||
const observation = start({
|
||||
scene: {
|
||||
postRender: {
|
||||
addEventListener(listener) {
|
||||
@@ -176,3 +178,89 @@ test('missing moveEnd frames fail without waiting for a render callback', async
|
||||
assert.equal(f.resources.listeners, 0);
|
||||
assert.equal(f.resources.timers, 0);
|
||||
});
|
||||
|
||||
// Let a retry's next attempt register its postRender listener.
|
||||
const settle = () => new Promise((resolve) => setImmediate(resolve));
|
||||
|
||||
function retryFixture() {
|
||||
const counts = { prepares: 0 };
|
||||
const f = fixture((options) =>
|
||||
observeArrivalRotationWithRetry({
|
||||
...options,
|
||||
async prepare() {
|
||||
counts.prepares++;
|
||||
},
|
||||
}),
|
||||
);
|
||||
f.counts = counts;
|
||||
return f;
|
||||
}
|
||||
|
||||
test('a wrong settle angle followed by a reveal timeout is final, not retried into a pass', async () => {
|
||||
const f = retryFixture();
|
||||
await settle();
|
||||
// 0.5 rad ≈ 29°: a real threshold violation on the settle frame.
|
||||
f.frame(8, { shown: true, rotationError: 0.5 });
|
||||
f.expire(508); // the reveal never comes inside its budget
|
||||
await settle();
|
||||
// An otherwise clean second attempt, which must never be started.
|
||||
f.frame(516, { shown: true, rotationError: 0 });
|
||||
f.frame(524, { shown: true, rotationError: 0 });
|
||||
const result = await f.observation;
|
||||
assert.match(result.error, /reveal.*500 ms/);
|
||||
assert.equal(result.dMoveEnd, 0.5, 'the measured settle angle is kept');
|
||||
assert.equal(arrivalAngleViolated(result), true);
|
||||
assert.equal(result.attempts, 1);
|
||||
assert.equal(f.counts.prepares, 1);
|
||||
assert.equal(f.resources.moveEnds, 1);
|
||||
assert.equal(arrivalRotationPassed(result), false);
|
||||
assert.equal(f.resources.listeners, 0);
|
||||
assert.equal(f.resources.timers, 0);
|
||||
});
|
||||
|
||||
test('an inconclusive reveal timeout after a correct settle earns one more attempt', async () => {
|
||||
const f = retryFixture();
|
||||
await settle();
|
||||
f.frame(8, { shown: true, rotationError: 0 });
|
||||
f.expire(508);
|
||||
await settle();
|
||||
f.frame(516, { shown: true, rotationError: 0 });
|
||||
f.frame(596, { shown: true, rotationError: 0 });
|
||||
const result = await f.observation;
|
||||
assert.equal(result.attempts, 2);
|
||||
assert.equal(f.counts.prepares, 2);
|
||||
assert.equal(f.resources.moveEnds, 2);
|
||||
assert.equal(arrivalRotationPassed(result), true);
|
||||
});
|
||||
|
||||
test('timeouts stop after the attempt limit and still fail', async () => {
|
||||
const f = retryFixture();
|
||||
await settle();
|
||||
f.expire(500);
|
||||
await settle();
|
||||
f.expire(1000);
|
||||
const result = await f.observation;
|
||||
assert.match(result.error, /moveEnd.*500 ms/);
|
||||
assert.equal(result.attempts, 2);
|
||||
assert.equal(arrivalRotationPassed(result), false);
|
||||
assert.equal(f.resources.listeners, 0);
|
||||
assert.equal(f.resources.timers, 0);
|
||||
});
|
||||
|
||||
test('a missing or non-finite angle never passes', () => {
|
||||
const clean = {
|
||||
shown: true,
|
||||
moveEndMs: 8,
|
||||
revealMs: 80,
|
||||
dMoveEnd: 0,
|
||||
dReveal: 0,
|
||||
};
|
||||
assert.equal(arrivalRotationPassed(clean), true);
|
||||
for (const field of ['dMoveEnd', 'dReveal']) {
|
||||
assert.equal(arrivalRotationPassed({ ...clean, [field]: NaN }), false);
|
||||
assert.equal(
|
||||
arrivalRotationPassed({ ...clean, [field]: undefined }),
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user