Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(compiler): improve JSII loading speed via binary format cache #3567

Merged
merged 43 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
4c9cccf
msgpack caching of imported jsii manifests (performance)
yoav-steinberg Jul 21, 2023
6095527
fix gzipped jsii caching (fingerprint is hash on entire gz file)
yoav-steinberg Jul 21, 2023
6c52403
use file metadata as cache fingerprint instead of jsii fingerprint
yoav-steinberg Jul 22, 2023
5ef101e
dep cleanup
yoav-steinberg Jul 22, 2023
f6c233b
cleanup
yoav-steinberg Jul 22, 2023
705054a
Merge branch 'main' into yoav/jsii_bin_cache
yoav-steinberg Jul 22, 2023
d938a70
use bincode instead of rmp_serde
yoav-steinberg Jul 23, 2023
5b9d653
fix (type inference issue)
yoav-steinberg Jul 23, 2023
5594f06
optimization: remove unecessary clone of imported jsii assembly
yoav-steinberg Jul 23, 2023
45c97f3
Merge branch 'main' into yoav/jsii_bin_cache
yoav-steinberg Jul 23, 2023
3c8560a
Merge branch 'main' into yoav/jsii_bin_cache
yoav-steinberg Jul 25, 2023
010d8dd
use `std::env::temp_dir()` instead of assuming `/tmp`
yoav-steinberg Jul 25, 2023
be3eb90
fix prev commit
yoav-steinberg Jul 25, 2023
225041a
use module version and name instead of path for manifest fingerprints
yoav-steinberg Jul 25, 2023
614d99b
store cache files by the .jsii manifest instead of temp dir
yoav-steinberg Jul 26, 2023
5173cdc
chore: self mutation
monadabot Jul 26, 2023
604666f
chore: self mutation
monadabot Jul 26, 2023
0d9b4f2
chore: self mutation
monadabot Jul 26, 2023
5c302b3
chore: self mutation
monadabot Jul 26, 2023
6915966
chore: self mutation
monadabot Jul 26, 2023
4f15004
chore: self mutation
monadabot Jul 26, 2023
8c39a30
Added test
yoav-steinberg Jul 26, 2023
73c4324
chore: self mutation
monadabot Jul 26, 2023
c1154dd
Update .gitignore
yoav-steinberg Jul 26, 2023
e0bc422
cleanup
yoav-steinberg Jul 27, 2023
42a592d
parse JSON from memory instead of from File
yoav-steinberg Jul 27, 2023
5436f6b
fix search dirs so we'll find the correct (dev) version of the sdk wh…
yoav-steinberg Jul 29, 2023
cac29db
tests
yoav-steinberg Jul 29, 2023
25c5890
lockfile update
yoav-steinberg Jul 29, 2023
2bc1eaa
udpate deps
yoav-steinberg Jul 29, 2023
cb0a21a
dbg
yoav-steinberg Jul 29, 2023
9361a63
dbg
yoav-steinberg Jul 29, 2023
996e320
dbg, cleanup, avoid race?
yoav-steinberg Jul 29, 2023
29dba71
dbg
yoav-steinberg Jul 29, 2023
21ff82f
dbg
yoav-steinberg Jul 30, 2023
9bda699
dbg
yoav-steinberg Jul 30, 2023
1be22d3
correct path to wingsdk in test
yoav-steinberg Jul 30, 2023
aa4fc25
revert debug stuff
yoav-steinberg Jul 30, 2023
87026e4
replace bincode with speedy (performance x2)
yoav-steinberg Jul 30, 2023
4f4d80b
typo
yoav-steinberg Jul 30, 2023
cc2c8c0
cr, cleanup
yoav-steinberg Aug 1, 2023
4f24ad1
Fix color output in compiler
yoav-steinberg Aug 1, 2023
18b33d0
Merge branch 'main' into yoav/jsii_bin_cache
yoav-steinberg Aug 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ node_modules/
# Generated wing output
*.w.out/

# Generated wingc .jsii binary cache
*.jsii.bincode
yoav-steinberg marked this conversation as resolved.
Show resolved Hide resolved

# cargo output
## will have compiled files and executables from cargo
debug/
Expand Down
101 changes: 101 additions & 0 deletions tools/hangar/src/jsii_cache.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { assert, expect, test } from "vitest";
import * as path from "path";
import fs from "fs/promises";
import { validTestDir, wingSdkDir } from "./paths";
import { runWingCommand } from "./utils";
import * as os from "os";

test("JSII manifest cache", async () => {
// Used awscdk test because it has manifest file redirects and uses gzip compression which is a good test case
// in addtion to regular manifest files
const app = "bring_awscdk.w";
const appFile = path.join(validTestDir, app);
const args = ["compile", "--target", "sim"];
const manifestCacheExt = ".jsii.bincode";

const awscdkLibDir = path.join(validTestDir, "node_modules", "aws-cdk-lib");

// Test manifest with redirect and gzip compression
await testManifestCache(awscdkLibDir);
// Test simple manifest file used by all wing apps
await testManifestCache(wingSdkDir);

async function testManifestCache(module_dir: string) {
// Get current time and wait a bit to make sure the cache file will have a different timestamp
const startTime = new Date();
await new Promise((resolve) => setTimeout(resolve, 2));

// Make sure the awscdk lib dir exists and we have access to it (will throw otherwise)
await fs.access(module_dir, fs.constants.W_OK | fs.constants.R_OK);

// Remove any existing manifest cache files
let files = (await fs.readdir(module_dir)).filter((file) => file.endsWith(manifestCacheExt));
for (const file of files) {
await fs.rm(path.join(module_dir, file));
}

// Compile the example (this should generate the manifest cache)
await runWingCommand({
cwd: validTestDir,
wingFile: appFile,
args,
expectFailure: false,
});

// Make sure the manifest cache file was generated
files = (await fs.readdir(module_dir)).filter((file) => file.endsWith(manifestCacheExt));
assert(files.length === 1);
let cache_file = files[0];
let stat = await fs.stat(path.join(module_dir, cache_file));
assert(stat.size > 0);
assert(stat.mtime > startTime);

// Wait a bit to make sure that if (for some reason) the manifest cache file is regenerated, it will have a different timestamp
await new Promise((resolve) => setTimeout(resolve, 2));

// Compile the example again (this should use the manifest cache)
await runWingCommand({
cwd: validTestDir,
wingFile: appFile,
args,
expectFailure: false,
});

// Make sure no new manifest cache file was generated
files = (await fs.readdir(module_dir)).filter((file) => file.endsWith(manifestCacheExt));
assert(files.length === 1);
assert(files[0] === cache_file);
let stat2 = await fs.stat(path.join(module_dir, cache_file));
assert(stat.size === stat2.size);
assert(stat.mtime.getTime() === stat2.mtime.getTime());

// Wait a bit so touching the manifest file will have a different timestamp and any generated cache file will also have a different timestamp
await new Promise((resolve) => setTimeout(resolve, 2));

// Touch the original manifest file and make sure the cache is regenerated
let manifestFile = path.join(module_dir, ".jsii");
const manifest = JSON.parse(await fs.readFile(manifestFile, "utf-8"));
// If this is a redirect the touch the target file instead
if (manifest.schema === "jsii/file-redirect") {
manifestFile = path.join(module_dir, manifest.filename);
}
await fs.utimes(manifestFile, new Date(), new Date());

// Compile the example again, this should regenerate the manifest cache and delete the old cache file
await runWingCommand({
cwd: validTestDir,
wingFile: appFile,
args,
expectFailure: false,
});

// Make sure the manifest cache file was generated and the old one was deleted
files = (await fs.readdir(module_dir)).filter((file) => file.endsWith(manifestCacheExt));
assert(files.length === 1);
assert(files[0] !== cache_file);
cache_file = files[0];
stat = await fs.stat(path.join(module_dir, cache_file));
assert(stat.size > 0);
assert(stat.mtime > stat2.mtime);
}
});
3 changes: 2 additions & 1 deletion tools/hangar/src/paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const errorTestDir = path.join(testDir, "error");
export const hangarDir = path.join(repoRoot, "tools/hangar");
export const tmpDir = path.join(hangarDir, "tmp");
export const npmCacheDir = path.join(tmpDir, ".npm");
export const wingSdkDir = path.join(repoRoot, "libs/wingsdk");

export const npmBin = path.join(hangarDir, "node_modules/.bin/npm");
export const wingBin = path.join(tmpDir, "node_modules/.bin/wing");
Expand All @@ -37,7 +38,7 @@ export const targetWingCompilerSpec =
`file:${path.join(repoRoot, `libs/wingcompiler`)}`;
export const targetWingSDKSpec =
process.env.HANGAR_WINGSDK_SPEC ??
`file:${path.join(repoRoot, `libs/wingsdk`)}`;
`file:${wingSdkDir}`;

export const validWingFiles = fs
.readdirSync(validTestDir)
Expand Down
Loading