perf: cache bundled channel entry resolution

This commit is contained in:
Peter Steinberger
2026-05-28 17:18:41 +01:00
parent 96635c7c27
commit a85ff92c05
2 changed files with 95 additions and 9 deletions
@@ -404,6 +404,54 @@ describe("loadBundledEntryExportSync", () => {
});
});
it("reuses resolved bundled sidecar paths before cached module exports", async () => {
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-channel-entry-contract-"));
tempDirs.push(tempRoot);
const pluginRoot = path.join(tempRoot, "dist", "extensions", "telegram");
fs.mkdirSync(pluginRoot, { recursive: true });
const importerPath = path.join(pluginRoot, "index.js");
const helperPath = path.join(pluginRoot, "helper.cjs");
fs.writeFileSync(importerPath, "export default {};\n", "utf8");
fs.writeFileSync(helperPath, "module.exports = { sentinel: 42 };\n", "utf8");
const openRootFileSync = vi.fn(() => ({
ok: true,
path: helperPath,
fd: fs.openSync(helperPath, "r"),
}));
vi.doMock("../infra/boundary-file-read.js", () => ({
openRootFileSync,
}));
try {
const channelEntryContract = await importFreshModule<
typeof import("./channel-entry-contract.js")
>(import.meta.url, "./channel-entry-contract.js?scope=resolved-sidecar-cache");
const ref = {
specifier: "./helper.cjs",
exportName: "sentinel",
};
expect(
channelEntryContract.loadBundledEntryExportSync<number>(
pathToFileURL(importerPath).href,
ref,
),
).toBe(42);
expect(
channelEntryContract.loadBundledEntryExportSync<number>(
pathToFileURL(importerPath).href,
ref,
),
).toBe(42);
expect(openRootFileSync).toHaveBeenCalledTimes(1);
} finally {
vi.doUnmock("../infra/boundary-file-read.js");
}
});
it("emits non-negative source-loader sub-step timings on the built-artifact load path", async () => {
// Built artifacts prefer `nodeRequire`, but Node can still reject a sidecar
// and fall back through jiti. The profile line must never report negative
+47 -9
View File
@@ -144,6 +144,8 @@ export type BundledEntryModuleLoadOptions = {
const nodeRequire = createRequire(import.meta.url);
const moduleLoaders: PluginModuleLoaderCache = new Map();
const entryBoundaryInfoCache = new Map<string, BundledEntryBoundaryInfo>();
const resolvedModulePaths = new Map<string, string>();
const loadedModuleExports = new Map<string, unknown>();
const disableBundledEntrySourceFallbackEnv = "OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK";
@@ -174,6 +176,38 @@ type BundledEntryModuleCandidate = {
boundaryRoot: string;
};
type BundledEntryBoundaryInfo = {
importerPath: string;
importerDir: string;
boundaryRoot: string;
packageRoot: string | null;
};
function resolveBundledEntryBoundaryInfo(importMetaUrl: string): BundledEntryBoundaryInfo {
const cacheKey = `${process.argv[1] ?? ""}\0${importMetaUrl}`;
const cached = entryBoundaryInfoCache.get(cacheKey);
if (cached) {
return cached;
}
const importerPath = fileURLToPath(importMetaUrl);
const importerDir = path.dirname(importerPath);
const boundaryRoot = path.dirname(importerPath);
const info = {
importerPath,
importerDir,
boundaryRoot,
packageRoot:
resolveLoaderPackageRoot({
modulePath: importerPath,
moduleUrl: importMetaUrl,
cwd: importerDir,
argv1: process.argv[1],
}) ?? null,
};
entryBoundaryInfoCache.set(cacheKey, info);
return info;
}
function addBundledEntryCandidates(
candidates: BundledEntryModuleCandidate[],
basePath: string,
@@ -193,9 +227,8 @@ function resolveBundledEntryModuleCandidates(
importMetaUrl: string,
specifier: string,
): BundledEntryModuleCandidate[] {
const importerPath = fileURLToPath(importMetaUrl);
const importerDir = path.dirname(importerPath);
const boundaryRoot = resolveEntryBoundaryRoot(importMetaUrl);
const { importerPath, importerDir, boundaryRoot, packageRoot } =
resolveBundledEntryBoundaryInfo(importMetaUrl);
const candidates: BundledEntryModuleCandidate[] = [];
const primaryResolved = path.resolve(importerDir, specifier);
addBundledEntryCandidates(candidates, primaryResolved, boundaryRoot);
@@ -209,12 +242,6 @@ function resolveBundledEntryModuleCandidates(
);
}
const packageRoot = resolveLoaderPackageRoot({
modulePath: importerPath,
moduleUrl: importMetaUrl,
cwd: importerDir,
argv1: process.argv[1],
});
if (!packageRoot) {
return candidates;
}
@@ -282,7 +309,17 @@ function formatBundledEntryModuleOpenFailure(params: {
].join(" ");
}
function createBundledEntryModulePathCacheKey(importMetaUrl: string, specifier: string): string {
const sourceFallbackDisabled = isTruthyEnvFlag(process.env[disableBundledEntrySourceFallbackEnv]);
return `${sourceFallbackDisabled ? "1" : "0"}\0${importMetaUrl}\0${specifier}`;
}
function resolveBundledEntryModulePath(importMetaUrl: string, specifier: string): string {
const cacheKey = createBundledEntryModulePathCacheKey(importMetaUrl, specifier);
const cached = resolvedModulePaths.get(cacheKey);
if (cached) {
return cached;
}
const candidates = resolveBundledEntryModuleCandidates(importMetaUrl, specifier);
const fallbackCandidate = candidates[0] ?? {
path: path.resolve(path.dirname(fileURLToPath(importMetaUrl)), specifier),
@@ -304,6 +341,7 @@ function resolveBundledEntryModulePath(importMetaUrl: string, specifier: string)
});
if (opened.ok) {
fs.closeSync(opened.fd);
resolvedModulePaths.set(cacheKey, opened.path);
return opened.path;
}
firstFailure ??= { candidate, failure: opened };