test(quality): add concurrency and real browser gates

This commit is contained in:
chick
2026-07-18 03:20:42 +08:00
parent 88d41a7a18
commit a884033352
5 changed files with 643 additions and 14 deletions
@@ -19,6 +19,7 @@ export type HealthSnapshotErrorCode =
export interface HealthSnapshotInstance {
readonly id: string;
readonly origin: string;
readonly revision: number;
}
export interface HealthEnvelope {
@@ -157,7 +158,32 @@ function transportErrorCode(error: unknown): SnapshotErrorCode {
return 'UPSTREAM_UNAVAILABLE';
}
const healthUrl = (origin: string): string => `${origin.replace(/\/$/, '')}/api/health`;
function isValidOwner(
instanceId: string,
owner: HealthSnapshotInstance | undefined,
): owner is HealthSnapshotInstance {
if (
!owner ||
owner.id !== instanceId ||
!Number.isSafeInteger(owner.revision) ||
owner.revision <= 0
) {
return false;
}
try {
const parsed = new URL(owner.origin);
return (
(parsed.protocol === 'http:' || parsed.protocol === 'https:') &&
parsed.origin === owner.origin &&
parsed.username === '' &&
parsed.password === ''
);
} catch {
return false;
}
}
const healthUrl = (origin: string): string => `${origin}/api/health`;
export class StatusSnapshotService {
readonly #db: Database.Database;
@@ -188,7 +214,7 @@ export class StatusSnapshotService {
async refreshHealth(instanceId: string): Promise<HealthSnapshot> {
const instance = await this.#instances.get(instanceId);
if (!instance) throw new StatusSnapshotError('INSTANCE_NOT_FOUND');
if (!isValidOwner(instanceId, instance)) throw new StatusSnapshotError('INSTANCE_NOT_FOUND');
const generation = ++this.#nextGeneration;
this.#latestGeneration.set(instanceId, generation);
@@ -201,6 +227,12 @@ export class StatusSnapshotService {
} catch (error) {
transportError = error;
}
let currentOwner: HealthSnapshotInstance | undefined;
try {
currentOwner = await this.#instances.get(instanceId);
} catch {
// Owner lookup failures fence persistence, but do not discard the computed probe result.
}
const completed = this.#now();
const observedAt = completed.toISOString();
const previous = this.#previous(instanceId);
@@ -216,7 +248,13 @@ export class StatusSnapshotService {
const { snapshot } = classified;
if (this.#latestGeneration.get(instanceId) === generation) {
this.#persist(snapshot, classified.persisted);
if (
isValidOwner(instanceId, currentOwner) &&
currentOwner.origin === instance.origin &&
currentOwner.revision === instance.revision
) {
this.#persist(instance, snapshot, classified.persisted);
}
this.#latestGeneration.delete(instanceId);
}
return Object.freeze({ ...snapshot, payload: Object.freeze({ ...snapshot.payload }) });
@@ -354,18 +392,23 @@ export class StatusSnapshotService {
};
}
#persist(snapshot: HealthSnapshot, persisted: PersistedHealthEnvelope): void {
#persist(
owner: HealthSnapshotInstance,
snapshot: HealthSnapshot,
persisted: PersistedHealthEnvelope,
): void {
this.#db
.prepare(
`INSERT INTO status_snapshots
(id,instance_id,category,state,payload_json,observed_at,expires_at,created_at)
SELECT ?,id,'health',?,?,?,?,? FROM instances WHERE id=?
SELECT ?,id,'health',?,?,?,?,? FROM instances
WHERE id=? AND base_url=? AND config_revision=?
ON CONFLICT(instance_id,category) DO UPDATE SET
state=excluded.state,
payload_json=excluded.payload_json,
observed_at=excluded.observed_at,
expires_at=excluded.expires_at
WHERE excluded.observed_at > status_snapshots.observed_at`,
WHERE excluded.observed_at >= status_snapshots.observed_at`,
)
.run(
this.#id(),
@@ -375,6 +418,8 @@ export class StatusSnapshotService {
snapshot.expiresAt,
snapshot.observedAt,
snapshot.instanceId,
owner.origin,
owner.revision,
);
}
}