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

chore(core): cache asset hashes #10478

Merged
merged 10 commits into from
Oct 5, 2020
Merged

chore(core): cache asset hashes #10478

merged 10 commits into from
Oct 5, 2020

Conversation

jogold
Copy link
Contributor

@jogold jogold commented Sep 22, 2020

Cache asset hashes. This avoids file system and bundling operations
when the same asset with the same configuration is used in multiple
stacks in an app.

Closes #9424


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

Cache asset hashes when staging. This avoids rebundling an asset with
`AssetHashType.OUTPUT` when it is used in multiple stacks in an app.

This also removes unnecessary file system operations for other asset
hash types.

Closes aws#9424
@jogold jogold changed the title chore(core): cache asset hashes chore(core): cache asset hashes when bundling Sep 22, 2020
Copy link
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small changes

// Check if we already bundled this source path in this App (e.g. the same
// asset is used in multiple stacks). In this case we can completely skip
// file system and bundling operations.
this.cacheHash = crypto.createHash('sha256')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe call this cacheKey, otherwise I get confused with all the occurrences of the word hash here.

Why does it need to be a member?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also feels like it would be cleaner if this calculation was in a function somewhere.

this.assetHashCache = {};
}

private static assetHashCache: { [key: string]: string } = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe in a comment what this does. It caches source hashes based on asset configuration.

Maybe also call it sourceHashCache?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name sourceHash is deprecated in favor of assetHash so I propose to stick with assetHashCache.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, I missed that. Alrighty.

// file system and bundling operations.
this.cacheHash = crypto.createHash('sha256')
.update(path.resolve(this.sourcePath))
.update(JSON.stringify(props.bundling))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has props.bundling been normalized yet? It probably needs to be, otherwise 2 sets of properties that morally represent the same asset configuration render to 2 different keys (I'm thinking for example of { packaging } specified or omitted because of the default)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Normalized" it by recursively sorting the keys after setting some defaults in the props.

.update(path.resolve(this.sourcePath))
.update(JSON.stringify(props.bundling))
.digest('hex');
if (AssetStaging.assetHashCache[this.cacheHash]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a small helper function makes this slightly nicer:

this.assetHash = AssetStaging.cachedSourceHash(cacheKey, () => {
  // ... calculation here...
});

(Or think of a nice other name)

@mergify mergify bot dismissed rix0rrr’s stale review September 30, 2020 18:20

Pull request has been modified.

@jogold jogold changed the title chore(core): cache asset hashes when bundling chore(core): cache asset hashes Sep 30, 2020
@jogold
Copy link
Contributor Author

jogold commented Sep 30, 2020

Changed to cache asset hash also when not bundling (avoids re-fingerprinting already fingerprinted dirs).

@jogold
Copy link
Contributor Author

jogold commented Sep 30, 2020

This (weird) test is now failing:

test('fingerprint data changes on asset hash update', () => {

In this test the content of an asset is changed with a fs.writeFileSync in the test... I don't expect this kind of manipulation to happen in the context of an App? + it only re-tests what's already tested in core.

@rix0rrr what do you say?

@jogold jogold requested a review from rix0rrr October 1, 2020 08:51
@rix0rrr
Copy link
Contributor

rix0rrr commented Oct 5, 2020

it only re-tests what's already tested in core.

It doesn't though. It also tests that the hash is reflected in UserData. I agree that it's a somewhat silly test that is taking advantage of a non-feature.

I think I would have preferred writing the same files to different asset locations (to avoid the cache), but the way you fixed it is fine too.

@mergify
Copy link
Contributor

mergify bot commented Oct 5, 2020

Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildProject6AEA49D1-qxepHUsryhcu
  • Commit ID: db9133f
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify
Copy link
Contributor

mergify bot commented Oct 5, 2020

Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bundling - multiple docker image builds
3 participants