feat(proxy-fitness): egress geo probe + unstable detection + state sweeper

Background probe fetches ipinfo through each pool itself (provider-agnostic
transport), fills an egress IP/country cache (TTL 1h, 8-IP history) and flags
flapping relays as unstable. Periodic state sweeper (10 min) prunes expired
fitness marks, stale geo/ip-history and Freebuff session/cooldown state;
schedulers skip non-server runtimes. Unit tests for the geo cache.
This commit is contained in:
MUH. IQRAM BAHRING
2026-08-07 03:51:29 +08:00
parent fd22290a34
commit b75d665fa5
5 changed files with 295 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
import { describe, it, expect, beforeEach } from "vitest";
import { setPoolGeo, getPoolGeo, poolGeoSnapshot, pruneStaleGeo, resetPoolGeo } from "open-sse/services/poolGeo.js";
describe("pool egress geo cache", () => {
beforeEach(() => resetPoolGeo());
it("stores geo and classifies stability from egress changes", () => {
setPoolGeo("p1", { ip: "1.1.1.1", country: "US" });
setPoolGeo("p1", { ip: "1.1.1.1", country: "US" }); // same IP twice
expect(getPoolGeo("p1").isUnstable).toBe(false);
expect(getPoolGeo("p1").ipCount).toBe(1);
setPoolGeo("p1", { ip: "2.2.2.2", country: "US" }); // changed
expect(getPoolGeo("p1").isUnstable).toBe(true);
expect(getPoolGeo("p1").ipCount).toBe(2);
});
it("prunes TTL-stale entries (ipHistory rides along)", () => {
setPoolGeo("p1", { ip: "1.1.1.1", country: "US" });
setPoolGeo("p1", { ip: "2.2.2.2", country: "US" });
const cache = globalThis["__9routerPoolGeo__"];
cache.get("p1").ts = Date.now() - 2 * 60 * 60 * 1000;
expect(pruneStaleGeo()).toBe(1);
expect(poolGeoSnapshot()).toEqual({});
});
});