源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { performance } from 'node:perf_hooks';
|
||||
import { mkdtemp, rm } from 'node:fs/promises';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { createSessionStore } from '@maka/storage/session-store';
|
||||
import { ClientSessionSubscription } from '../dist/client/session-subscription.js';
|
||||
import { SESSION_CONTINUITY_SCHEMA_VERSION } from '../dist/protocol/index.js';
|
||||
import {
|
||||
createSessionTranscriptBootstrap,
|
||||
readSessionTranscriptPage,
|
||||
} from '../dist/server/session-transcript-pager.js';
|
||||
|
||||
const BOOTSTRAP_BYTES = 16 * 1024;
|
||||
const RTT_MS = Number.parseInt(process.env.MAKA_TRANSCRIPT_BENCHMARK_RTT_MS ?? '20', 10);
|
||||
const cases = [
|
||||
{ name: '5k-small-messages', messages: 5_000, textBytes: 96 },
|
||||
{ name: '15MiB-single-message', messages: 1, textBytes: 15 * 1024 * 1024 },
|
||||
{ name: '17MiB-transcript', totalBytes: 17 * 1024 * 1024, textBytes: 4 * 1024 },
|
||||
{ name: '64MiB-transcript', totalBytes: 64 * 1024 * 1024, textBytes: 4 * 1024 },
|
||||
];
|
||||
|
||||
const results = [];
|
||||
for (const fixture of cases) results.push(await runFixture(fixture));
|
||||
console.table(results);
|
||||
|
||||
async function runFixture(fixture) {
|
||||
const messages = buildMessages(fixture);
|
||||
const root = await mkdtemp(join(tmpdir(), 'maka-transcript-benchmark-'));
|
||||
const store = createSessionStore(root);
|
||||
const setupAt = performance.now();
|
||||
const session = await store.create({
|
||||
cwd: root,
|
||||
backend: 'fake',
|
||||
llmConnectionSlug: 'fake',
|
||||
model: 'fake-model',
|
||||
permissionMode: 'ask',
|
||||
name: fixture.name,
|
||||
labels: [],
|
||||
});
|
||||
await store.appendMessages(session.id, messages);
|
||||
const setupMs = performance.now() - setupAt;
|
||||
const reader = sqliteReader(store);
|
||||
try {
|
||||
const openedAt = performance.now();
|
||||
const throughSequence = await reader.readDurableHighWater(session.id);
|
||||
const { bootstrap, state } = await createSessionTranscriptBootstrap({
|
||||
reader,
|
||||
sessionId: session.id,
|
||||
subscriptionId: `benchmark-${fixture.name}`,
|
||||
throughSequence,
|
||||
rootTurn: null,
|
||||
activeAssistantStreams: [],
|
||||
maxBytes: BOOTSTRAP_BYTES,
|
||||
});
|
||||
const bootstrapCpuMs = performance.now() - openedAt;
|
||||
let pageRequests = 0;
|
||||
let transferredRawBytes = bootstrap.durable.rawBytes + bootstrap.overlay.rawBytes;
|
||||
const subscription = new ClientSessionSubscription(
|
||||
{
|
||||
hostEpoch: 'benchmark-host',
|
||||
subscriptionId: state.subscriptionId,
|
||||
nextSequence: 1,
|
||||
activeAssistantStreams: [],
|
||||
transcript: bootstrap,
|
||||
snapshot: {
|
||||
schemaVersion: SESSION_CONTINUITY_SCHEMA_VERSION,
|
||||
session: {
|
||||
sessionId: state.sessionId,
|
||||
metadataRevision: 1,
|
||||
status: 'active',
|
||||
createdAt: 1,
|
||||
isArchived: false,
|
||||
},
|
||||
projectionRevision: 1,
|
||||
rootTurn: null,
|
||||
goal: null,
|
||||
queue: {
|
||||
hostEpoch: 'benchmark-host',
|
||||
queueRevision: 0,
|
||||
steering: [],
|
||||
followup: [],
|
||||
},
|
||||
interactions: { pending: [] },
|
||||
},
|
||||
},
|
||||
async () => undefined,
|
||||
async (request) => {
|
||||
pageRequests += 1;
|
||||
const page = await readSessionTranscriptPage({ reader, state, request });
|
||||
transferredRawBytes += page.rawBytes;
|
||||
return page;
|
||||
},
|
||||
);
|
||||
const materializeAt = performance.now();
|
||||
const materialized = await subscription.loadTranscript((value) => value);
|
||||
const materializeCpuMs = performance.now() - materializeAt;
|
||||
if (materialized.length !== messages.length) {
|
||||
throw new Error(
|
||||
`${fixture.name} materialized ${materialized.length}/${messages.length} messages`,
|
||||
);
|
||||
}
|
||||
const wireRequests = 1 + pageRequests;
|
||||
return {
|
||||
fixture: fixture.name,
|
||||
messages: messages.length,
|
||||
rawMiB: decimalMiB(transferredRawBytes),
|
||||
bootstrapKiB: decimalKiB(bootstrap.durable.rawBytes + bootstrap.overlay.rawBytes),
|
||||
wireRequests,
|
||||
pageRequests,
|
||||
setupMs: setupMs.toFixed(1),
|
||||
bootstrapCpuMs: bootstrapCpuMs.toFixed(1),
|
||||
materializeCpuMs: materializeCpuMs.toFixed(1),
|
||||
modeledRttFloorMs: wireRequests * RTT_MS,
|
||||
};
|
||||
} finally {
|
||||
await store.close?.();
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
function buildMessages(fixture) {
|
||||
const messages = [];
|
||||
let encodedBytes = 0;
|
||||
const targetCount = fixture.messages ?? Number.POSITIVE_INFINITY;
|
||||
while (
|
||||
messages.length < targetCount &&
|
||||
(fixture.totalBytes === undefined || encodedBytes < fixture.totalBytes)
|
||||
) {
|
||||
const index = messages.length;
|
||||
const message = {
|
||||
type: 'user',
|
||||
id: `message-${index}`,
|
||||
turnId: `turn-${index}`,
|
||||
ts: index + 1,
|
||||
text: 'x'.repeat(fixture.textBytes),
|
||||
};
|
||||
messages.push(message);
|
||||
encodedBytes += Buffer.byteLength(JSON.stringify(message), 'utf8');
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
function sqliteReader(store) {
|
||||
return {
|
||||
readDurableHighWater: (sessionId) => store.readTranscriptHighWaterSnapshot(sessionId),
|
||||
readDurablePage: (sessionId, request) => store.readTranscriptPageSnapshot(sessionId, request),
|
||||
readDurableMessagesById: (sessionId, messageIds, throughSequence) =>
|
||||
store.readTranscriptMessagesSnapshot(sessionId, messageIds, throughSequence),
|
||||
readActiveOverlay: async () => [],
|
||||
};
|
||||
}
|
||||
|
||||
function decimalMiB(bytes) {
|
||||
return (bytes / (1024 * 1024)).toFixed(2);
|
||||
}
|
||||
|
||||
function decimalKiB(bytes) {
|
||||
return (bytes / 1024).toFixed(2);
|
||||
}
|
||||
Reference in New Issue
Block a user