




















@@ -613,14 +613,31 @@ function rememberAppendedSessionEntry(
613613beforeAppendSnapshot: SessionFileSnapshot | undefined,
614614serializedAppend: string,
615615cacheOwnedAppend: boolean,
616-): { snapshot: SessionFileSnapshot | undefined; cacheAdvanced: boolean } {
616+publishOwnedAppend: boolean,
617+): {
618+snapshot: SessionFileSnapshot | undefined;
619+cacheAdvanced: boolean;
620+ownedAppendVerified: boolean;
621+} {
617622const resolvedPath = resolve(filePath);
623+const appendedByteLength = BigInt(Buffer.byteLength(serializedAppend, "utf8"));
624+const isVerifiedOwnedAppend = (snapshot: SessionFileSnapshot | undefined) =>
625+Boolean(
626+publishOwnedAppend &&
627+beforeAppendSnapshot &&
628+snapshot &&
629+snapshot.dev === beforeAppendSnapshot.dev &&
630+snapshot.ino === beforeAppendSnapshot.ino &&
631+snapshot.size === beforeAppendSnapshot.size + appendedByteLength,
632+);
618633if (!cacheOwnedAppend) {
619634sessionEntriesCache.delete(resolvedPath);
620635invalidateSessionFileRepairCache(resolvedPath);
636+const snapshot = readSessionFileSnapshotIfExists(resolvedPath);
621637return {
622-snapshot: readSessionFileSnapshotIfExists(resolvedPath),
638+ snapshot,
623639cacheAdvanced: false,
640+ownedAppendVerified: isVerifiedOwnedAppend(snapshot),
624641};
625642}
626643if (
@@ -633,6 +650,7 @@ function rememberAppendedSessionEntry(
633650return {
634651snapshot: readSessionFileSnapshotIfExists(resolvedPath),
635652cacheAdvanced: false,
653+ownedAppendVerified: false,
636654};
637655}
638656@@ -641,8 +659,7 @@ function rememberAppendedSessionEntry(
641659// Owned transcript writes serialize appenders under the session lock. Full
642660// rewrites refresh the cache explicitly, so identity and size are sufficient
643661// to advance this append-only snapshot without reading the whole file.
644-const expectedSize =
645-beforeAppendSnapshot.size + BigInt(Buffer.byteLength(serializedAppend, "utf8"));
662+const expectedSize = beforeAppendSnapshot.size + appendedByteLength;
646663if (
647664!snapshot ||
648665!cached ||
@@ -655,11 +672,11 @@ function rememberAppendedSessionEntry(
655672) {
656673sessionEntriesCache.delete(resolvedPath);
657674invalidateSessionFileRepairCache(resolvedPath);
658-return { snapshot, cacheAdvanced: false };
675+return { snapshot, cacheAdvanced: false, ownedAppendVerified: false };
659676}
660677if (snapshot.size > MAX_CACHED_SESSION_BYTES) {
661678sessionEntriesCache.delete(resolvedPath);
662-return { snapshot, cacheAdvanced: false };
679+return { snapshot, cacheAdvanced: false, ownedAppendVerified: true };
663680}
664681665682const persistedEntry = JSON.parse(
@@ -671,7 +688,7 @@ function rememberAppendedSessionEntry(
671688sessionEntriesCache.delete(resolvedPath);
672689sessionEntriesCache.set(resolvedPath, cached);
673690trimSessionEntriesCache();
674-return { snapshot, cacheAdvanced: true };
691+return { snapshot, cacheAdvanced: true, ownedAppendVerified: true };
675692}
676693677694function publishRememberedSessionFileSnapshot(
@@ -688,6 +705,15 @@ function publishRememberedSessionFileSnapshot(
688705}
689706}
690707708+function canIncrementallyCacheAppendedEntry(entry: SessionEntry): boolean {
709+return !(
710+entry.type === "custom" ||
711+entry.type === "custom_message" ||
712+entry.type === "compaction" ||
713+entry.type === "branch_summary"
714+);
715+}
716+691717function readSessionFileSnapshotIfExists(filePath: string): SessionFileSnapshot | undefined {
692718try {
693719return readSessionFileSnapshot(filePath);
@@ -1328,13 +1354,16 @@ export class SessionManager {
13281354// prefix state that immediately precedes the exact bytes being appended.
13291355const serializedEntry = serializeJsonlEntry(entry);
13301356const beforeAppendSnapshot = readSessionFileSnapshotIfExists(this.sessionFile);
1331-const cacheOwnedAppend = Boolean(
1357+const canPublishOwnedAppend = Boolean(
13321358beforeAppendSnapshot &&
13331359canAdvanceOwnedSessionEntryCache({
13341360sessionFile: this.sessionFile,
13351361snapshot: beforeAppendSnapshot,
13361362}),
13371363);
1364+// Extension/detail-bearing entries can run arbitrary toJSON code while
1365+// serializing, so stat-only append validation is too weak for them.
1366+const cacheOwnedAppend = canPublishOwnedAppend && canIncrementallyCacheAppendedEntry(entry);
13381367const serializedAppend = appendSerializedJsonlEntrySync(this.sessionFile, serializedEntry, {
13391368prefixNewline: sessionFileNeedsAppendSeparator(this.sessionFile, beforeAppendSnapshot),
13401369});
@@ -1344,9 +1373,10 @@ export class SessionManager {
13441373beforeAppendSnapshot,
13451374serializedAppend,
13461375cacheOwnedAppend,
1376+canPublishOwnedAppend,
13471377);
13481378this.sessionFileSnapshot = rememberedAppend.snapshot;
1349-if (rememberedAppend.cacheAdvanced) {
1379+if (rememberedAppend.ownedAppendVerified) {
13501380publishRememberedSessionFileSnapshot(this.sessionFile, rememberedAppend.snapshot);
13511381}
13521382}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。