perf(main): avoid repeated lead session tail scans
This commit is contained in:
parent
4b5a49e6e8
commit
b32cc59b46
2 changed files with 20 additions and 43 deletions
|
|
@ -3247,41 +3247,25 @@ export class TeamDataService {
|
||||||
|
|
||||||
private async readLeadSessionJsonlTailLines(jsonlPath: string): Promise<string[]> {
|
private async readLeadSessionJsonlTailLines(jsonlPath: string): Promise<string[]> {
|
||||||
const MAX_SCAN_BYTES = 8 * 1024 * 1024;
|
const MAX_SCAN_BYTES = 8 * 1024 * 1024;
|
||||||
const INITIAL_SCAN_BYTES = 256 * 1024;
|
|
||||||
|
|
||||||
const rawLinesReversed: string[] = [];
|
|
||||||
const seenRawLines = new Set<string>();
|
|
||||||
const handle = await fs.promises.open(jsonlPath, 'r');
|
const handle = await fs.promises.open(jsonlPath, 'r');
|
||||||
try {
|
try {
|
||||||
const stat = await handle.stat();
|
const stat = await handle.stat();
|
||||||
const fileSize = stat.size;
|
const fileSize = stat.size;
|
||||||
|
const scanBytes = Math.min(MAX_SCAN_BYTES, fileSize);
|
||||||
|
const start = Math.max(0, fileSize - scanBytes);
|
||||||
|
const buffer = Buffer.alloc(scanBytes);
|
||||||
|
await handle.read(buffer, 0, scanBytes, start);
|
||||||
|
const chunk = buffer.toString('utf8');
|
||||||
|
|
||||||
let scanBytes = Math.min(INITIAL_SCAN_BYTES, fileSize);
|
const lines = chunk.split(/\r?\n/);
|
||||||
while (scanBytes <= MAX_SCAN_BYTES) {
|
const fromIndex = start > 0 ? 1 : 0;
|
||||||
const start = Math.max(0, fileSize - scanBytes);
|
return lines
|
||||||
const buffer = Buffer.alloc(scanBytes);
|
.slice(fromIndex)
|
||||||
await handle.read(buffer, 0, scanBytes, start);
|
.map((line) => line.trim())
|
||||||
const chunk = buffer.toString('utf8');
|
.filter(Boolean);
|
||||||
|
|
||||||
const lines = chunk.split(/\r?\n/);
|
|
||||||
const fromIndex = start > 0 ? 1 : 0;
|
|
||||||
|
|
||||||
for (let i = lines.length - 1; i >= fromIndex; i--) {
|
|
||||||
const trimmed = lines[i]?.trim();
|
|
||||||
if (!trimmed) continue;
|
|
||||||
if (seenRawLines.has(trimmed)) continue;
|
|
||||||
seenRawLines.add(trimmed);
|
|
||||||
rawLinesReversed.push(trimmed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scanBytes === fileSize) break;
|
|
||||||
scanBytes = Math.min(fileSize, scanBytes * 2);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
await handle.close();
|
await handle.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return rawLinesReversed.reverse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async extractLeadAssistantTextsFromJsonlLines(
|
private async extractLeadAssistantTextsFromJsonlLines(
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import type { ParsedMessage } from '@main/types';
|
||||||
import type { CommandOutputMeta, InboxMessage, SlashCommandMeta } from '@shared/types';
|
import type { CommandOutputMeta, InboxMessage, SlashCommandMeta } from '@shared/types';
|
||||||
|
|
||||||
const MAX_SCAN_BYTES = 8 * 1024 * 1024;
|
const MAX_SCAN_BYTES = 8 * 1024 * 1024;
|
||||||
const INITIAL_SCAN_BYTES = 256 * 1024;
|
|
||||||
|
|
||||||
interface LeadSessionMessageExtractorOptions {
|
interface LeadSessionMessageExtractorOptions {
|
||||||
jsonlPath: string;
|
jsonlPath: string;
|
||||||
|
|
@ -133,23 +132,17 @@ export async function extractLeadSessionMessagesFromJsonl({
|
||||||
try {
|
try {
|
||||||
const stat = await handle.stat();
|
const stat = await handle.stat();
|
||||||
const fileSize = stat.size;
|
const fileSize = stat.size;
|
||||||
|
const scanBytes = Math.min(MAX_SCAN_BYTES, fileSize);
|
||||||
|
const start = Math.max(0, fileSize - scanBytes);
|
||||||
|
const buffer = Buffer.alloc(scanBytes);
|
||||||
|
await handle.read(buffer, 0, scanBytes, start);
|
||||||
|
const chunk = buffer.toString('utf8');
|
||||||
|
|
||||||
let scanBytes = Math.min(INITIAL_SCAN_BYTES, fileSize);
|
const lines = chunk.split(/\r?\n/);
|
||||||
while (scanBytes <= MAX_SCAN_BYTES) {
|
const fromIndex = start > 0 ? 1 : 0;
|
||||||
const start = Math.max(0, fileSize - scanBytes);
|
|
||||||
const buffer = Buffer.alloc(scanBytes);
|
|
||||||
await handle.read(buffer, 0, scanBytes, start);
|
|
||||||
const chunk = buffer.toString('utf8');
|
|
||||||
|
|
||||||
const lines = chunk.split(/\r?\n/);
|
for (let i = lines.length - 1; i >= fromIndex; i--) {
|
||||||
const fromIndex = start > 0 ? 1 : 0;
|
collectLine(lines[i]);
|
||||||
|
|
||||||
for (let i = lines.length - 1; i >= fromIndex; i--) {
|
|
||||||
collectLine(lines[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scanBytes === fileSize) break;
|
|
||||||
scanBytes = Math.min(fileSize, scanBytes * 2);
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await handle.close();
|
await handle.close();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue