Keep HTTP responsive during confluence replay.
Boot replay was a tight CPU loop that wedged the Unraid backend, so login hit the 8s client timeout. Yield every few as-of dates, shorten the boot ledger fill, and make /health a cheap liveness check.
This commit is contained in:
@@ -301,7 +301,12 @@ export async function runConfluenceReplay(
|
||||
const weeklyFull = await provider.resolveAsOf(symbol, '1wk', '9999-12-31');
|
||||
const benchFull = await provider.resolveAsOf(BENCHMARK_SYMBOL, '1d', '9999-12-31');
|
||||
|
||||
let asOfN = 0;
|
||||
for (const asOf of slice) {
|
||||
asOfN += 1;
|
||||
if (asOfN % 4 === 0) {
|
||||
await new Promise<void>((r) => setImmediate(r));
|
||||
}
|
||||
const dailyCut = daily.candles.filter((c) => (c.ts ?? '').slice(0, 10) <= asOf);
|
||||
const weeklyCut = weeklyFull.candles.filter((c) => (c.ts ?? '').slice(0, 10) <= asOf);
|
||||
const benchCut = benchFull.candles.filter((c) => (c.ts ?? '').slice(0, 10) <= asOf);
|
||||
@@ -391,6 +396,7 @@ export async function fillLearningLedger(
|
||||
complete: batch.complete,
|
||||
};
|
||||
if (batch.evaluationsStored === 0) break;
|
||||
await new Promise<void>((r) => setImmediate(r));
|
||||
}
|
||||
return { ...last, ledger: await learningLedgerStatus(db, cache) };
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ async function confluenceTick(label: string): Promise<void> {
|
||||
} = await import('./confluence/confluenceEngine.ts');
|
||||
const { CONFLUENCE_LEARNING_UNIVERSE } = await import('./confluence/confluenceSeed.ts');
|
||||
const replay = label === 'boot'
|
||||
? await fillLearningLedger(database, cache, 75_000)
|
||||
? await fillLearningLedger(database, cache, 12_000)
|
||||
: await runConfluenceReplay(database, cache, {
|
||||
symbols: CONFLUENCE_LEARNING_UNIVERSE,
|
||||
symbolsPerTick: LEARNING_REPLAY_SYMBOLS,
|
||||
@@ -331,7 +331,9 @@ const server = createServer(async (req, res) => {
|
||||
const url = new URL(req.url ?? '/', `http://localhost:${PORT}`);
|
||||
if (url.pathname === '/health') {
|
||||
res.writeHead(200, { 'content-type': 'application/json' });
|
||||
res.end(JSON.stringify({ ok: true, queue: queue.health() }));
|
||||
// Cheap liveness only. queue.health() is a full SQLite scan and must not
|
||||
// ride the docker healthcheck / login path.
|
||||
res.end(JSON.stringify({ ok: true }));
|
||||
return;
|
||||
}
|
||||
if (url.pathname.startsWith('/api/trpc')) {
|
||||
|
||||
+2
-1
@@ -1008,7 +1008,8 @@ export const api = {
|
||||
},
|
||||
auth: {
|
||||
signup: (email: string, password: string) => trpcMutate<{ userId: string }>("auth.signup", { email, password }),
|
||||
login: (email: string, password: string, totp?: string) => trpcMutate<{ userId: string }>("auth.login", { email, password, ...(totp ? { totp } : {}) }),
|
||||
login: (email: string, password: string, totp?: string) =>
|
||||
trpcMutate<{ userId: string }>("auth.login", { email, password, ...(totp ? { totp } : {}) }, 20_000),
|
||||
logout: () => trpcMutate<{ ok: boolean }>("auth.logout", {}),
|
||||
changePassword: (current: string, next: string) =>
|
||||
trpcMutate<{ ok: boolean }>("auth.changePassword", { current, next }),
|
||||
|
||||
Reference in New Issue
Block a user