Skip to content
This repository has been archived by the owner on May 14, 2018. It is now read-only.

side effects cache #38

Merged
merged 14 commits into from
Jan 22, 2018
Merged

side effects cache #38

merged 14 commits into from
Jan 22, 2018

Conversation

etamponi
Copy link
Member

No description provided.

Copy link
Member

@zkochan zkochan left a comment

Choose a reason for hiding this comment

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

Should be covered with tests

@@ -124,6 +128,8 @@ const defaults = async (opts: InstallOptions) => {
verifyStoreIntegrity: true,
hooks: {},
savePrefix: '^',
sideEffectsCache: false,
Copy link
Member

Choose a reason for hiding this comment

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

We'll probably make it true by default in the future

@@ -573,13 +575,19 @@ async function installInContext (
R.props<string, DependencyTreeNode>(result.newPkgResolvedIds, result.linkedPkgsMap)
.map(pkg => limitChild(async () => {
try {
await postInstall(pkg.peripheralLocation, {
if (pkg.importedFromCache) {
Copy link
Member

Choose a reason for hiding this comment

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

move this check to a filter function before .map()

}
) {
return Promise.all(
alldeps.map(async pkg => {
const filesResponse = await pkg.fetchingFiles

if (pkg.independent) return
return storeController.importPackage(pkg.centralLocation, pkg.peripheralLocation, {

let importFrom = pkg.centralLocation
Copy link
Member

Choose a reason for hiding this comment

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

just change the value of centralLocation to the path that will be used here, so move this logic with sideEffectsCache to resolvePeers and assign centralLocation the correct value

@@ -53,6 +53,8 @@ export type DependencyTreeNode = {
cpu?: string[],
os?: string[],
},
sideEffectsCache: Map<string, string>,
importedFromCache?: boolean,
Copy link
Member

Choose a reason for hiding this comment

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

Might be better to be more specific here, so importedFromSideEffectsCache or isBuilt or skipScripts

@@ -403,7 +408,8 @@ async function install (
engines: pkg.engines,
cpu: pkg.cpu,
os: pkg.os,
}
},
sideEffectsCache: pkgResponse.body.sideEffectsCache,
Copy link
Member

@zkochan zkochan Jan 18, 2018

Choose a reason for hiding this comment

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

Just assign one value to it

sideEffectsCacheLocation: pkgResponse.body.sideEffectsCache[nodeMajor],

also, I'd suggest renaming the map to pkgResponse.body.sideEffectsCacheByEngine or pkgResponse.body.sideEffectsCacheByNodeVersion

I think it would be even fine to make it shorter pkgResponse.body.cacheByNodeVersion, as this is the only type of cache that depends on Node/engine

Copy link
Member

Choose a reason for hiding this comment

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

also, when options.force is true, then always assign null to the sifeEffectsCacheLocation. In that case, cache will be rewritten

const nodeMajor = process.version.substring(0, process.version.indexOf('.'))
if (node.sideEffectsCache && node.sideEffectsCache[nodeMajor]) {
node.isBuilt = true
node.centralLocation = node.sideEffectsCache[nodeMajor]
Copy link
Member

@zkochan zkochan Jan 18, 2018

Choose a reason for hiding this comment

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

assign these two values right where the node is created:

ctx.resolvedTree[absolutePath] = {

it is much easier to read the code when all properties of the object are set in one place and stay immutable

Copy link
Member Author

Choose a reason for hiding this comment

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

I couldn't find where the node was created, that's why :) Ok 👍

@@ -409,7 +410,7 @@ async function install (
cpu: pkg.cpu,
os: pkg.os,
},
sideEffectsCache: pkgResponse.body.sideEffectsCache,
cacheByNodeVersion: ctx.force ? '' : pkgResponse.body.sideEffectsCache[nodeMajor],
Copy link
Member

Choose a reason for hiding this comment

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

you can make this property nullable and assign it null or undefined. The empty string doesn't make sense

@@ -185,7 +179,8 @@ function resolvePeersOfNode (
hasBundledDependencies: node.pkg.hasBundledDependencies,
fetchingFiles: node.pkg.fetchingFiles,
resolution: node.pkg.resolution,
centralLocation,
centralLocation: node.pkg.cacheByNodeVersion || centralLocation,
Copy link
Member

Choose a reason for hiding this comment

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

You'll have to change it here:

const centralLocation = path.join(node.pkg.path, 'node_modules', node.pkg.name)

centralLocation is used for peripheralLocation sometimes, so it should have the correct value

@@ -385,6 +385,7 @@ async function install (

const peerDependencies = peerDependenciesWithoutOwn(pkg)

const nodeMajor = process.version.substring(0, process.version.indexOf('.'))
Copy link
Member

Choose a reason for hiding this comment

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

move this line to the beginning of the file. It is enough to calculate nodeMajor once. There is no need to recalculate it on each function call

@@ -403,7 +410,8 @@ async function install (
engines: pkg.engines,
cpu: pkg.cpu,
os: pkg.os,
}
},
cacheByNodeVersion: ctx.force || pkgResponse.body.sideEffectsCache[NODE_MAJOR],
Copy link
Member

@zkochan zkochan Jan 19, 2018

Choose a reason for hiding this comment

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

actually, it can be simplified even more.

This object has a property called path. path is used only once, when centralLocation is assigned. So central location can be calculated here, instead of in resolvePeers.ts. In that case this object will need to contain one property instead of two. So only centralLocation instead of path and cacheByNodeVersion

Copy link
Member Author

Choose a reason for hiding this comment

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

And how do we mark isBuilt? Do we really need to do this? It seems more complicated to me.

Copy link
Member

Choose a reason for hiding this comment

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

isBuilt can be added to this object as well

Copy link
Member

@zkochan zkochan Jan 19, 2018

Choose a reason for hiding this comment

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

but maybe lets wait with this. I am still thinking about our discussion in package-requester. If the cache can depend on dependency set, this code will have to be changed more and in a different place

Copy link
Member Author

Choose a reason for hiding this comment

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

So we are replacing one field for another? I started doing what you asked for and I had to add way more lines of code than those I removed... Should I go ahead? Really?

@@ -36,7 +36,8 @@ export default async function postInstall (
await npmRunScript('preinstall', pkg, scriptsOpts)
await npmRunScript('install', pkg, scriptsOpts)
await npmRunScript('postinstall', pkg, scriptsOpts)
return

return !!scripts['preinstall'] || !!scripts['install'] || !!scripts['postinstall']
Copy link
Member

Choose a reason for hiding this comment

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

this is too much I think. We only want to cache compilation of native libs. Some lifecycle script might do necessary things. Like husky configures git hooks

Copy link
Member Author

@etamponi etamponi Jan 20, 2018

Choose a reason for hiding this comment

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

Well, if there were an easy way to only cache that, it would be great. Is there? Perhaps we could only cache preinstall and install, and always run postinstall.

Again, this is what zeit claims to do, I am sticking with that.

EDIT: additionally, I would like to cache everything, not only compilation of native libs... my goal is to make installation very very fast on Glitch projects, so I'd like to cache as much as possible.

@etamponi
Copy link
Member Author

Question: --side-effects-cache-readonly should automatically turn --side-effects-cache to true, right? Like, I shouldn't need to do pnpm install --side-effects-cache --side-effects-cache-readonly, but just pnpm install --side-effects-cache-readonly, right?

@zkochan
Copy link
Member

zkochan commented Jan 21, 2018

Vice versa, --side-effects-cache should turn --side-effects-cache-readonly to true

@etamponi
Copy link
Member Author

What?

@etamponi
Copy link
Member Author

Let me clarify:

  1. pnpm install --side-effects-cache: use & create side effects cache
  2. pnpm install --side-effects-cache-readonly: use & NOT create side effects cache
  3. pnpm install --side-effects-cache --side-effects-cache-readonly: same as previous, but redundant.

That's what I would expect the behaviour to be.

@zkochan
Copy link
Member

zkochan commented Jan 21, 2018

yes, I agree. The 3rd one could be even an error or a warning

Copy link
Member

@zkochan zkochan left a comment

Choose a reason for hiding this comment

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

I'd suggest one more test that would verify that the side effects cache is overwritten when installing with force: true.

It is possible to test it by comparing one of the files' ino number before/after the second install

await installPkgs(['runas@3.1.1'], opts)

// Modify the side effects cache to make sure we are using it
// TODO this test won't work anymore when we introduce integrity.json
Copy link
Member

Choose a reason for hiding this comment

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

it will be possible to make it work by specifying verifyStoreIntegrity: false

@zkochan
Copy link
Member

zkochan commented Jan 21, 2018

We should probably add "node" to the side effects cache dirname because it's currently unclear what the v4 at the end means. So something lik linux-x64-node-v4

@zkochan zkochan merged commit 0985078 into master Jan 22, 2018
@zkochan
Copy link
Member

zkochan commented Jan 22, 2018

🚢 0.12.0

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

Successfully merging this pull request may close these issues.

2 participants