Skip to content

Commit fb47cba

Browse files
fix(web): the diff worker pool keeps one subscription and size without memoization
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent bb80e99 commit fb47cba

1 file changed

Lines changed: 20 additions & 16 deletions

File tree

‎apps/web/src/components/DiffWorkerPoolProvider.tsx‎

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { WorkerPoolManager } from "@pierre/diffs/worker";
33
import DiffsWorker from "@pierre/diffs/worker/worker.js?worker";
44
import * as Schema from "effect/Schema";
55
import { useEffect, useState, useSyncExternalStore, type ReactNode } from "react";
6+
import { useStableCallback } from "../hooks/useStableCallback";
67
import { useTheme } from "../hooks/useTheme";
78
import { resolveDiffThemeName, type DiffThemeName } from "../lib/diffRendering";
89
import { PREFERRED_HIGHLIGHTER } from "../lib/syntaxHighlighting";
@@ -18,11 +19,11 @@ export class DiffWorkerError extends Schema.TaggedError<DiffWorkerError>()("Diff
1819
}
1920

2021
const DIFF_WORKER_IDLE_TTL_MS = 30_000;
21-
const DIFF_WORKER_POOL_SIZE = (() => {
22+
function resolveDiffWorkerPoolSize() {
2223
const cores =
2324
typeof navigator === "undefined" ? 4 : Math.max(1, navigator.hardwareConcurrency || 4);
2425
return Math.max(2, Math.min(6, Math.floor(cores / 2)));
25-
})();
26+
}
2627
let sharedWorkerPool:
2728
| {
2829
readonly pool: WorkerPoolManager;
@@ -127,21 +128,24 @@ function DiffWorkerReady({ children }: { children?: ReactNode }) {
127128
export function DiffWorkerPoolProvider({ children }: { children?: ReactNode }) {
128129
const { resolvedTheme } = useTheme();
129130
const diffThemeName = resolveDiffThemeName(resolvedTheme);
131+
const [workerPoolSize] = useState(resolveDiffWorkerPoolSize);
132+
// A new subscribe identity makes React release and reacquire the shared pool on every render.
133+
const subscribe = useStableCallback((onStoreChange: () => void) => {
134+
if (typeof window === "undefined") return () => {};
135+
const entry = acquireDiffWorkerPool(diffThemeName, workerPoolSize);
136+
onStoreChange();
137+
return () => {
138+
entry.consumers -= 1;
139+
if (entry.consumers !== 0) return;
140+
entry.idleTimer = setTimeout(() => {
141+
entry.idleTimer = undefined;
142+
entry.pool.terminate();
143+
if (sharedWorkerPool === entry) sharedWorkerPool = undefined;
144+
}, DIFF_WORKER_IDLE_TTL_MS);
145+
};
146+
});
130147
const workerPool = useSyncExternalStore(
131-
(onStoreChange) => {
132-
if (typeof window === "undefined") return () => {};
133-
const entry = acquireDiffWorkerPool(diffThemeName, DIFF_WORKER_POOL_SIZE);
134-
onStoreChange();
135-
return () => {
136-
entry.consumers -= 1;
137-
if (entry.consumers !== 0) return;
138-
entry.idleTimer = setTimeout(() => {
139-
entry.idleTimer = undefined;
140-
entry.pool.terminate();
141-
if (sharedWorkerPool === entry) sharedWorkerPool = undefined;
142-
}, DIFF_WORKER_IDLE_TTL_MS);
143-
};
144-
},
148+
subscribe,
145149
() => sharedWorkerPool?.pool,
146150
() => undefined,
147151
);

0 commit comments

Comments
 (0)