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

Add cache for downloaded binary files #1566

Closed
wants to merge 6 commits into from
Closed

Add cache for downloaded binary files #1566

wants to merge 6 commits into from

Conversation

mriehema
Copy link

  • The binary file is downloaded to a tmp folder and copied to vendor destination. If the binary already exist in the tmp folder, it will be copied only.
  • With this change node-sass will work offline, cache the binary and save bandwidth.
  • The binary configuration parameters will work the same as before.

Fixes #1554.

- the binary file is downloaded to a tmp folder and copied to vendor destination. If the binary already exist in the tmp folder, it will be copied only.
- With this change node-sass will work offline, cache the binary and save bandwidth.
- The binary configuration parameters will work the same as before.
@xzyfer
Copy link
Contributor

xzyfer commented May 26, 2016

Thanks for this @mriehema. Generally speak it looks good. I'll take a closer look over the weekend.

One thing, I don't like the addition of fs-extras just for mkdir -p. I'd prefer you changed this to use mkdirp instead.

@xzyfer
Copy link
Contributor

xzyfer commented May 27, 2016

Thanks for that update @mriehema.

@saper @nschonni I'd love for y'all to be over this as well.

@nschonni
Copy link
Contributor

The code looks OK, but can't this just be achieved as-is by passing the temp directory (or the expression to test for what temp directory) to the existing SASS_BINARY_PATH

@xzyfer
Copy link
Contributor

xzyfer commented May 27, 2016

@nschonni there was a bunch of prior discussion in #1554. This is a comprise of sorts.

@nschonni
Copy link
Contributor

I did read it, but apparently totally missed 2.
This will cause even more problems for when people change node versions:

  1. Install node-sass 3.7, binary gets copied to temp
  2. Upgrade node to 3.8, and rerun install. Copies over 3.7 binary from temp again
  3. Clear all node_modules like our usual troubleshooting, still grabs node 3.7 binary from temp

I think a general extension point for people wanting to change the download behaviour might be something to consider.
If this one is going to proceed, it'll need some other folder layer to indicate node-sass version or at least version testing like PhantomJS uses to see if it can use the version in temp path.

@xzyfer
Copy link
Contributor

xzyfer commented May 27, 2016

@nschonni I'm not sure I'm following. The intent of this change is just changing the download directory from vendor to something out side of node_modules i.e. /tmp. The copying the downloaded binary to vendor. The idea being if you rm -rf node_modules subsequent install will hit disk before the network.

We will not be changing the directory structure at all so the version switching issue is no different than it is today. The thing that does changes is that rm -rf node_modules is not guaranteed to fetch the latest binary, but since binaries are immutable this is a non-issue.

I haven't had time confirmed the implementation here respects those constraints but it wont ship with out it.

return;
}
var tmpPath = getTempPath(sass.getBinaryName());
if (!(sass.hasBinary(tmpPath))) { // download and install
Copy link
Contributor

Choose a reason for hiding this comment

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

@xzyfer this is the part I'm saying will always fall back to the first installed binary file in the temp folder

Copy link
Contributor

Choose a reason for hiding this comment

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

As I said I've haven't look over the implementation yet. It's entirely likely there are issues that will need to be addressed.

Copy link
Author

@mriehema mriehema May 27, 2016

Choose a reason for hiding this comment

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

The name of the binary file in the tmp folder based on sass.getBinaryName(). E.g. win32-x64-47_binding.node, not just binding.node. If you use another version of node-sass, the name will change too.

Copy link
Contributor

@xzyfer xzyfer May 27, 2016

Choose a reason for hiding this comment

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

You're both correct. The binaries won't clash on different node/arch/os
combinations. However because we're no longer within node_modules changing
versions of node-sass would be an issue. When changing versions of
node-sass the installer would see a binary for their environment on disk
but it would not the correct binary for their node-sass version.

You'll need to create a folder for the node-sass version for this to work
as intended.

@mriehema
Copy link
Author

The idea being if you rm -rf node_modules subsequent install will hit disk before the network.

Exactly.

We will not be changing the directory structure at all so the version switching issue is no different than it is today.

Correct. I kept everything the same, but split download and install the binary into two different steps and added a "temp layer".

@saper
Copy link
Member

saper commented May 30, 2016

I think it goes towards a pretty good think. Can we have the cache format the same as for node-sass-binaries repository? In short, checking it out from git somewhere should be the easiest way to fill the cache.

@xzyfer
Copy link
Contributor

xzyfer commented May 30, 2016

I think this approach is solid as long as the binaries are downloaded into
a node-sass version specific temp directory.

@mriehema
Copy link
Author

mriehema commented May 31, 2016

I added the package version as subfolder to the temp path. It looks now like the file-structure of a release.

Example:
Web: https://github.com/sass/node-sass/releases/download/v3.7.0/win32-x64-47_binding.node
Temp Win7: C:\Users\mriehema\AppData\Local\Temp\node-sass\releases\download\v3.7.0\win32-x64-47_binding.node

@saper, you should be able to easily fill the cache with scrips now.
@xzyfer, any more issues, questions, problems to be resolved?

function getTempPath(binaryName) {
var candidateTmpDirs = [
process.env.TMPDIR || process.env.TEMP || process.env.npm_config_tmp,
'/tmp',
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

process.env.TMPDIR is the same as os-tmpdir. Line 140 is a fallback, which should never be reached. These lines are copied from the install script of phantomjs. They use it long ago without any problems.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's ok, I'd still prefer you use a tested package that abstracts away this concern.

- simplify getTempPath()
- use os-tmpdir
- add fallback to vendor
- remove unnecessary parameters
@mriehema
Copy link
Author

mriehema commented Jun 7, 2016

@xzyfer, still something missing, or does this this PR look good to you now?

@xzyfer
Copy link
Contributor

xzyfer commented Jun 7, 2016

Sorry @mriehema we don't get notified of new commits so I didn't see these changes.

*/

function getTempPath() {
var candidateTmpDir = tmpdir() || process.env.npm_config_tmp;
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't correct anymore. It's not either or, it's an array of candidates. What you used to have was correct.

var candidateTmpDirs = [
  tmpdir(), 
  process.env.npm_config_tmp, 
  sass.getBinaryPath(),
];

Copy link
Author

Choose a reason for hiding this comment

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

Please take a look at the whole function. I removed the unnecessary foreach() loop of this list. It's now either tmpdir(), or process.env.npm_config_tmp. If they fail, sass.getBinaryPath() is used as fallback.

Maybe we should (temporary) disable the skip_ci part of this install script to test it on your CI.

Copy link
Contributor

Choose a reason for hiding this comment

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

I saw the change and IMHO it's incorrect since tmpdir() can never return a falsy value. Also, even if there is a tmpdir there is no guarantee it can be written to. The previous behaviour was correct because it asserted that either tmpdir() or process.env.npm_config_tmp existed and could be written to.

nschonni added a commit to nschonni/node-sass that referenced this pull request Sep 9, 2016
New order of operations
1. Look for existing binary in vendor folder
2. Create target vendor folder
3. Look to see if we’ve cached a copy in the NPM cache for this version
4. Download to current version’s cached NPM download
5. Copy the NPM cached version to the regular vendor directory
Lookup the configured NPM cache folder.
Closes sass#1566
nschonni added a commit to nschonni/node-sass that referenced this pull request Sep 9, 2016
New order of operations
1. Look for existing binary in vendor folder
2. Create target vendor folder
3. Look to see if we’ve cached a copy in the NPM cache for this version
4. Download to current version’s cached NPM download
5. Copy the NPM cached version to the regular vendor directory
Lookup the configured NPM cache folder.
Closes sass#1566
@mriehema
Copy link
Author

mriehema commented Sep 9, 2016

Closed. A) not mergable, B) see #1714

@mriehema mriehema closed this Sep 9, 2016
@nschonni nschonni modified the milestones: 3.11.0, next.minor Sep 15, 2016
nschonni added a commit to nschonni/node-sass that referenced this pull request Sep 23, 2016
New order of operations
1. Look for existing binary in vendor folder
2. Create target vendor folder
3. Look to see if we’ve cached a copy in the configured or NPM cache
4. Download to current version’s /CACHE/node-sass/version/binding_file
5. Copy the cached download to the regular vendor directory
Closes sass#1566
nschonni added a commit to nschonni/node-sass that referenced this pull request Sep 25, 2016
New order of operations
1. Look for existing binary in vendor folder
2. Create target vendor folder
3. Look to see if we’ve cached a copy in the configured or NPM cache
4. Download to current version’s /CACHE/node-sass/version/binding_file
5. Copy the cached download to the regular vendor directory
Closes sass#1566
nschonni added a commit to nschonni/node-sass that referenced this pull request Oct 2, 2016
New order of operations
1. Look for existing binary in vendor folder
2. Create target vendor folder
3. Look to see if we’ve cached a copy in the configured or NPM cache
4. Download to current version’s /CACHE/node-sass/version/binding_file
5. Copy the cached download to the regular vendor directory
Closes sass#1566
@mriehema mriehema deleted the issue-1554-cache-binary branch October 4, 2016 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants