feat(ql3): expose bounded worker session observation

This commit is contained in:
whyour
2026-08-20 12:55:44 +08:00
parent 6265e31dce
commit 4a4fa85f51
24 changed files with 1437 additions and 28 deletions
@@ -119,6 +119,7 @@ test('defines the immutable PostgreSQL capability and Run core stream', async ()
'pg-0066-cancellation-dispatch',
'pg-0067-cancellation-dispatch-management',
'pg-0068-cancellation-dispatch-project-keyset',
'pg-0069-worker-session-management-observation',
],
);
for (const migration of postgresqlMainMigrationStream.migrations) {
@@ -597,6 +598,11 @@ test('freezes every published PostgreSQL migration checksum', () => {
checksum:
'2fcac38386581189db63faacff325356f11c4529a8db9cef6be1a1ca706aaf10',
},
{
id: 'pg-0069-worker-session-management-observation',
checksum:
'1191255575589abc2686b391827607abddb4edb78007245dbaaf45dc1c4e5e8b',
},
];
assert.deepEqual(
postgresqlMainMigrationStream.migrations.map(({ id, checksum }) => ({
@@ -2421,3 +2427,36 @@ test('advances capability v67 with a Project-scoped blocked keyset', async () =>
/migration_id = 'pg-0067-cancellation-dispatch-management'/,
);
});
test('advances capability v68 with read-only Worker session observation', async () => {
const migration = migrationById(
'pg-0069-worker-session-management-observation',
);
const statements = [];
await migration.up({
async query(statement) {
statements.push(statement);
return { rows: [] };
},
});
const sql = statements.join('\n');
assert.match(
sql,
/REVOKE ALL ON "ql3"\."worker_sessions" FROM ql3_worker_credential_manager/,
);
assert.match(
sql,
/GRANT SELECT ON "ql3"\."worker_sessions" TO ql3_worker_credential_manager/,
);
assert.doesNotMatch(
sql,
/GRANT (?:INSERT|UPDATE|DELETE|TRUNCATE)[^;]+worker_sessions[^;]+ql3_worker_credential_manager/,
);
assert.match(sql, /contract_version = 68/);
assert.match(sql, /"worker_session_observation":1/);
assert.match(sql, /contract_version = 67/);
assert.match(
sql,
/migration_id = 'pg-0068-cancellation-dispatch-project-keyset'/,
);
});
@@ -561,6 +561,7 @@ function workerCredentialPrivileges(kind) {
? [
'worker_credential_management_quota_buckets',
'plugin_package_identity_keyset_ledger',
'worker_sessions',
]
: []),
...(manager
@@ -835,7 +836,7 @@ test('accepts the exact PostgreSQL control schema and least-privilege runtime ro
serverMajor: 16,
currentUser: 'ql3_runtime',
contractName: 'control-core',
contractVersion: 67,
contractVersion: 68,
migrationIds: [
'pg-0001-schema-capability',
'pg-0002-run-core',
@@ -905,6 +906,7 @@ test('accepts the exact PostgreSQL control schema and least-privilege runtime ro
'pg-0066-cancellation-dispatch',
'pg-0067-cancellation-dispatch-management',
'pg-0068-cancellation-dispatch-project-keyset',
'pg-0069-worker-session-management-observation',
],
});
});
@@ -935,10 +937,10 @@ test('accepts the exact schema and isolated least-privilege admin role', async (
}),
);
assert.equal(report.currentUser, 'ql3_admin');
assert.equal(report.contractVersion, 67);
assert.equal(report.contractVersion, 68);
assert.equal(
report.migrationIds.at(-1),
'pg-0068-cancellation-dispatch-project-keyset',
'pg-0069-worker-session-management-observation',
);
});
@@ -951,10 +953,10 @@ test('accepts the isolated least-privilege automation manager role', async () =>
}),
);
assert.equal(report.currentUser, 'ql3_automation_manager');
assert.equal(report.contractVersion, 67);
assert.equal(report.contractVersion, 68);
assert.equal(
report.migrationIds.at(-1),
'pg-0068-cancellation-dispatch-project-keyset',
'pg-0069-worker-session-management-observation',
);
const widened = automationManagerPrivileges();
@@ -983,10 +985,10 @@ test('accepts the isolated least-privilege human Approval manager role', async (
}),
);
assert.equal(report.currentUser, 'ql3_approval_manager');
assert.equal(report.contractVersion, 67);
assert.equal(report.contractVersion, 68);
assert.equal(
report.migrationIds.at(-1),
'pg-0068-cancellation-dispatch-project-keyset',
'pg-0069-worker-session-management-observation',
);
const widened = approvalManagerPrivileges();
@@ -1017,10 +1019,10 @@ test('accepts the isolated least-privilege Run manager role', async () => {
}),
);
assert.equal(report.currentUser, 'ql3_run_manager');
assert.equal(report.contractVersion, 67);
assert.equal(report.contractVersion, 68);
assert.equal(
report.migrationIds.at(-1),
'pg-0068-cancellation-dispatch-project-keyset',
'pg-0069-worker-session-management-observation',
);
const widened = runManagerPrivileges();
@@ -1181,10 +1183,10 @@ test('accepts the exact schema and isolated Worker ingress role', async () => {
}),
);
assert.equal(report.currentUser, 'ql3_worker_ingress');
assert.equal(report.contractVersion, 67);
assert.equal(report.contractVersion, 68);
assert.equal(
report.migrationIds.at(-1),
'pg-0068-cancellation-dispatch-project-keyset',
'pg-0069-worker-session-management-observation',
);
});
@@ -0,0 +1,119 @@
const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
canonicalRemoteWorkerCapabilities,
} = require('@qinglong/runtime-core/remote-dispatch');
const {
PostgresWorkerSessionObservationRepository,
} = require('@qinglong/cluster-postgres/worker-credential-manager');
function row(index, overrides = {}) {
const canonical = canonicalRemoteWorkerCapabilities(
overrides.capabilities ?? {
architecture: index % 2 === 0 ? 'arm64' : 's390x',
executors: ['remote-worker'],
protocolVersion: '1.0.0',
supportTier: index % 2 === 0 ? 'tier1' : 'candidate',
runtimes: [{ name: 'node', version: '24.18.0' }],
},
);
return {
observedAtMs: 2_000,
workerId: `worker-${String(index).padStart(2, '0')}`,
sessionId: `018f0f5d-7b6a-7a11-8f4d-${String(index + 1).padStart(
12,
'0',
)}`,
generation: 1,
status: 'online',
version: 2,
capabilitiesJson: canonical.json,
capabilitiesHash: canonical.hash,
maxConcurrentRuns: 4,
availableSlots: 2,
registeredAtMs: 1_000,
lastHeartbeatAtMs: 1_900,
leaseExpiresAtMs: 3_000,
updatedAtMs: 1_900,
...Object.fromEntries(
Object.entries(overrides).filter(([key]) => key !== 'capabilities'),
),
};
}
test('inspects one exact Worker without exposing raw capability content', async () => {
const queries = [];
const repository = new PostgresWorkerSessionObservationRepository({
async query(text, values) {
queries.push({ text, values });
return { rows: [row(0)], rowCount: 1 };
},
});
const result = await repository.inspect('worker-00');
assert.equal(result.observedAtMs, 2_000);
assert.equal(result.worker.workerId, 'worker-00');
assert.equal(result.worker.compatibility, 'default_placement');
assert.deepEqual(result.worker.runtimes, [
{ name: 'node', version: '24.18.0' },
]);
assert.equal(Object.hasOwn(result.worker, 'capabilitiesJson'), false);
assert.deepEqual(queries[0].values, ['worker-00']);
assert.match(queries[0].text, /LIMIT 2/);
});
test('returns a masked absent inspection and a fixed sixteen-item keyset page', async () => {
let call = 0;
const repository = new PostgresWorkerSessionObservationRepository({
async query(_text, values) {
call += 1;
if (call === 1) {
return {
rows: [{ observedAtMs: 2_000, workerId: null }],
rowCount: 1,
};
}
assert.deepEqual(values, [null, 17]);
return {
rows: Array.from({ length: 17 }, (_, index) => row(index)),
rowCount: 17,
};
},
});
assert.deepEqual(await repository.inspect('missing-worker'), {
observedAtMs: 2_000,
worker: null,
});
const page = await repository.list(null);
assert.equal(page.workers.length, 16);
assert.equal(page.nextCursor, 'worker-15');
assert.equal(page.workers[1].compatibility, 'explicit_placement_required');
assert.equal(Object.hasOwn(page.workers[0], 'runtimes'), false);
assert.equal(Object.hasOwn(page.workers[0], 'declaredCapacity'), false);
});
test('fails closed on identity, ordering and database-clock drift', async () => {
const identity = new PostgresWorkerSessionObservationRepository({
async query() {
return { rows: [row(1)], rowCount: 1 };
},
});
await assert.rejects(identity.inspect('worker-00'), /identity drifted/);
const unordered = new PostgresWorkerSessionObservationRepository({
async query() {
return { rows: [row(1), row(0)], rowCount: 2 };
},
});
await assert.rejects(unordered.list(null), /page is unordered/);
const clock = new PostgresWorkerSessionObservationRepository({
async query() {
return {
rows: [row(0), row(1, { observedAtMs: 2_001 })],
rowCount: 2,
};
},
});
await assert.rejects(clock.list(null), /clock drifted/);
});