Speed up trust: cache the tracking start, index reviews by reviewer, use attempts.score
The admin Authors table computed trust for all 121 agents in ~30 s, blocking the web process (arcade, admin, everything) meanwhile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7120dcaebc
commit
b4f8f6d630
3 changed files with 8 additions and 4 deletions
|
|
@ -322,6 +322,7 @@ export class Store {
|
||||||
this.addColumn('attempts', 'competing', 'INTEGER NOT NULL DEFAULT 0');
|
this.addColumn('attempts', 'competing', 'INTEGER NOT NULL DEFAULT 0');
|
||||||
this.db.exec('CREATE INDEX IF NOT EXISTS events_type_at ON events(type, at)'); // merge rates, feed
|
this.db.exec('CREATE INDEX IF NOT EXISTS events_type_at ON events(type, at)'); // merge rates, feed
|
||||||
this.db.exec('CREATE INDEX IF NOT EXISTS attempts_batch ON attempts(batch_id)');
|
this.db.exec('CREATE INDEX IF NOT EXISTS attempts_batch ON attempts(batch_id)');
|
||||||
|
this.db.exec('CREATE INDEX IF NOT EXISTS peer_reviews_reviewer ON peer_reviews(reviewer_id, created_at)'); // reviewer trust
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Submitted files of an attempt (kept once per batch). */
|
/** Submitted files of an attempt (kept once per batch). */
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,9 @@ export class Trust {
|
||||||
// Rows of this agent: its token, plus the account's untracked work if the token is that old.
|
// Rows of this agent: its token, plus the account's untracked work if the token is that old.
|
||||||
scope(alias, tokenId) {
|
scope(alias, tokenId) {
|
||||||
if (tokenId == null) return { sql: `${alias}.token_id IS NULL`, args: [] };
|
if (tokenId == null) return { sql: `${alias}.token_id IS NULL`, args: [] };
|
||||||
const started = this.store.get('SELECT MIN(created_at) AS at FROM batches WHERE token_id IS NOT NULL')?.at ?? now();
|
// When batches started recording their token: fixed once known (batches are numbered in time).
|
||||||
|
this.started ??= this.store.get('SELECT created_at AS at FROM batches WHERE token_id IS NOT NULL ORDER BY id LIMIT 1')?.at;
|
||||||
|
const started = this.started ?? now();
|
||||||
const created = this.store.get('SELECT created_at FROM api_tokens WHERE id = ?', tokenId)?.created_at ?? now();
|
const created = this.store.get('SELECT created_at FROM api_tokens WHERE id = ?', tokenId)?.created_at ?? now();
|
||||||
return created < started ? { sql: `(${alias}.token_id = ? OR ${alias}.token_id IS NULL)`, args: [tokenId] } : { sql: `${alias}.token_id = ?`, args: [tokenId] };
|
return created < started ? { sql: `(${alias}.token_id = ? OR ${alias}.token_id IS NULL)`, args: [tokenId] } : { sql: `${alias}.token_id = ?`, args: [tokenId] };
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +93,7 @@ export class Trust {
|
||||||
`SELECT SUM(same >= CASE WHEN different > 0 THEN ? ELSE ? END AND different < ?) AS accepted, SUM(different >= ?) AS rejected FROM (
|
`SELECT SUM(same >= CASE WHEN different > 0 THEN ? ELSE ? END AND different < ?) AS accepted, SUM(different >= ?) AS rejected FROM (
|
||||||
SELECT ${w('same')} AS same, ${w('different')} AS different FROM attempts a
|
SELECT ${w('same')} AS same, ${w('different')} AS different FROM attempts a
|
||||||
WHERE a.user_id = ? AND ${s.sql} AND a.created_at > ? AND a.kind = 'code' AND a.peer_skipped = 0
|
WHERE a.user_id = ? AND ${s.sql} AND a.created_at > ? AND a.kind = 'code' AND a.peer_skipped = 0
|
||||||
AND json_extract(a.result_json, '$.feedback.target.score') >= ?)`,
|
AND a.score >= ?)`,
|
||||||
this.autoAccept, this.acceptClean, this.required, this.required, userId, ...s.args, now() - p.authorDays * DAY, p.bandAt,
|
this.autoAccept, this.acceptClean, this.required, this.required, userId, ...s.args, now() - p.authorDays * DAY, p.bandAt,
|
||||||
);
|
);
|
||||||
const accepted = r?.accepted ?? 0;
|
const accepted = r?.accepted ?? 0;
|
||||||
|
|
@ -144,5 +146,6 @@ export class Trust {
|
||||||
|
|
||||||
forget() {
|
forget() {
|
||||||
this.cache.clear();
|
this.cache.clear();
|
||||||
|
this.started = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1345,8 +1345,8 @@ test('trust: careful reviewers count more, trusted authors skip peer review, one
|
||||||
await mk(3, 'trustpeer');
|
await mk(3, 'trustpeer');
|
||||||
const peers = [0, 1, 2].map((i) => ctx.accounts.byName(`trustpeer${i}`));
|
const peers = [0, 1, 2].map((i) => ctx.accounts.byName(`trustpeer${i}`));
|
||||||
const attempt = (userId, tokenId, score, state = 'merged') =>
|
const attempt = (userId, tokenId, score, state = 'merged') =>
|
||||||
Number(ctx.store.run(`INSERT INTO attempts (task_id, user_id, token_id, base_commit, files_json, state, result_json, created_at) VALUES (?, ?, ?, ?, '{}', ?, ?, ?)`,
|
Number(ctx.store.run(`INSERT INTO attempts (task_id, user_id, token_id, base_commit, files_json, state, score, result_json, created_at) VALUES (?, ?, ?, ?, '{}', ?, ?, ?, ?)`,
|
||||||
task, userId, tokenId, head, state, JSON.stringify({ feedback: { target: { score } } }), now()).lastInsertRowid);
|
task, userId, tokenId, head, state, score, JSON.stringify({ feedback: { target: { score } } }), now()).lastInsertRowid);
|
||||||
const verdict = (a, userId, v, tokenId = null) =>
|
const verdict = (a, userId, v, tokenId = null) =>
|
||||||
ctx.store.run(`INSERT INTO peer_reviews (attempt_id, reviewer_id, token_id, verdict, reason, created_at) VALUES (?, ?, ?, ?, 'the loop bound and the call match the original', ?)`, a, userId, tokenId, v, now());
|
ctx.store.run(`INSERT INTO peer_reviews (attempt_id, reviewer_id, token_id, verdict, reason, created_at) VALUES (?, ?, ?, ?, 'the loop bound and the call match the original', ?)`, a, userId, tokenId, v, now());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue