Skip to content

Commit 63141a0

Browse files
improve version check speed for already downloaded versions (#21881)
As part of making it so I can locally test [AB#8548](https://dev.azure.com/fluidframework/235294da-091d-4c29-84fc-cdfc3d90890b/_workitems/edit/8548) I haven't tested this for remote builds, but this sped up my local runs of loader back-compat downloads significantly from minutes to a few seconds. Even though the remote builds will need to download all the builds, this speeds up the process of reading whether or not a build was installed. My guess is that there likely will be pipeline speed reductions. Locally, running back compat full tests will be significantly faster as indicated above because we will not need to read the file for every single version that we have installed, instead we will read the file once for all installed versions.
1 parent 2fb3bdf commit 63141a0

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

packages/test/test-version-utils/src/versionUtils.ts

+20-12
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import * as path from "node:path";
1818
import { fileURLToPath, pathToFileURL } from "node:url";
1919

2020
import { detectVersionScheme, fromInternalScheme } from "@fluid-tools/version-tools";
21-
import { assert } from "@fluidframework/core-utils/internal";
21+
import { LazyPromise, assert } from "@fluidframework/core-utils/internal";
2222
import { lock } from "proper-lockfile";
2323
import * as semver from "semver";
2424

@@ -40,6 +40,12 @@ interface InstalledJson {
4040
installed: string[];
4141
}
4242

43+
let cachedInstalledJson: InstalledJson | undefined;
44+
function writeAndUpdateInstalledJson(data: InstalledJson) {
45+
cachedInstalledJson = data;
46+
writeFileSync(installedJsonPath, JSON.stringify(data, undefined, 2), { encoding: "utf8" });
47+
}
48+
4349
async function ensureInstalledJson() {
4450
if (existsSync(installedJsonPath)) {
4551
return;
@@ -54,11 +60,12 @@ async function ensureInstalledJson() {
5460
mkdirSync(baseModulePath, { recursive: true });
5561
const data: InstalledJson = { revision, installed: [] };
5662

57-
writeFileSync(installedJsonPath, JSON.stringify(data, undefined, 2), { encoding: "utf8" });
63+
writeAndUpdateInstalledJson(data);
5864
} finally {
5965
release();
6066
}
6167
}
68+
const ensureInstalledJsonLazy = new LazyPromise(async () => ensureInstalledJson());
6269

6370
function readInstalledJsonNoLock(): InstalledJson {
6471
const data = readFileSync(installedJsonPath, { encoding: "utf8" });
@@ -67,46 +74,47 @@ function readInstalledJsonNoLock(): InstalledJson {
6774
// if the revision doesn't match assume that it doesn't match
6875
return { revision, installed: [] };
6976
}
77+
cachedInstalledJson = installedJson;
7078
return installedJson;
7179
}
7280

7381
async function readInstalledJson(): Promise<InstalledJson> {
74-
await ensureInstalledJson();
82+
await ensureInstalledJsonLazy;
7583
const release = await lock(installedJsonPath, { retries: { forever: true } });
7684
try {
7785
return readInstalledJsonNoLock();
7886
} finally {
7987
release();
8088
}
8189
}
90+
const readInstalledJsonLazy = new LazyPromise(async () => readInstalledJson());
91+
async function getInstalledJson(): Promise<InstalledJson> {
92+
return cachedInstalledJson ?? (await readInstalledJsonLazy);
93+
}
8294

8395
const isInstalled = async (version: string) =>
84-
(await readInstalledJson()).installed.includes(version);
96+
(await getInstalledJson()).installed.includes(version);
8597
async function addInstalled(version: string) {
86-
await ensureInstalledJson();
98+
await ensureInstalledJsonLazy;
8799
const release = await lock(installedJsonPath, { retries: { forever: true } });
88100
try {
89101
const installedJson = readInstalledJsonNoLock();
90102
if (!installedJson.installed.includes(version)) {
91103
installedJson.installed.push(version);
92-
writeFileSync(installedJsonPath, JSON.stringify(installedJson, undefined, 2), {
93-
encoding: "utf8",
94-
});
104+
writeAndUpdateInstalledJson(installedJson);
95105
}
96106
} finally {
97107
release();
98108
}
99109
}
100110

101111
async function removeInstalled(version: string) {
102-
await ensureInstalledJson();
112+
await ensureInstalledJsonLazy;
103113
const release = await lock(installedJsonPath, { retries: { forever: true } });
104114
try {
105115
const installedJson = readInstalledJsonNoLock();
106116
installedJson.installed = installedJson.installed.filter((value) => value !== version);
107-
writeFileSync(installedJsonPath, JSON.stringify(installedJson, undefined, 2), {
108-
encoding: "utf8",
109-
});
117+
writeAndUpdateInstalledJson(installedJson);
110118
} finally {
111119
release();
112120
}

0 commit comments

Comments
 (0)