Skip to content

Conversation

@bestander
Copy link
Member

@bestander bestander commented Mar 2, 2017

Summary

A mitigation for #2629
Also fixes #961

Based on a few ad-hoc tests (//gitlab.com/linagora/petals-cockpit.git#075bac4c54fee466568c000c7ffe8025f593e212) tar-fs seems to make less IO thus is more stable and a bit faster.

I noticed that we never tested git repos that support archive.
Did they ever work?


Test data:

  1. Using offline-mirror (no download), on my MBPro 13", clean cache and using node-tar to unzip files.
    Concurrency 12 - fails
    Concurrency 8 - 18 seconds
    Concurrency 4 - 18 seconds
    Concurrency 2 - 21 seconds

  2. Using offline-mirror (no download), on my MBPro 13", clean cache and using tar-fs to unzip files.
    Concurrency 12 - 15 seconds
    Concurrency 8 - 15 seconds
    Concurrency 4 - 17 seconds
    Concurrency 2 - 18 seconds

  3. Downloading packages from internet, on my MBPro 13", clean cache and using tar-fs to unzip files.
    Concurrency 12 - failed once
    Concurrency 8 - 21 seconds
    Concurrency 4 - 23 seconds
    Concurrency 2 - 34 seconds

Test plan

  • All changes are covered with tests (verified every change)
  • Could not properly test git archives (see git archive capability works? #2831) but did an ad-hoc test via yarn add ssh://[email protected]/bestander/test-repo.git and made sure that archive was accessed and installed.

@bestander bestander changed the title Set default network concurrency to 8 and switched to tar-fs instead of node-tar [WIP] Set default network concurrency to 8 and switched to tar-fs instead of node-tar Mar 2, 2017
@bestander bestander changed the title [WIP] Set default network concurrency to 8 and switched to tar-fs instead of node-tar [WIP] switched to tar-fs from node-tar to unpack tars Mar 3, 2017
@bestander bestander changed the title [WIP] switched to tar-fs from node-tar to unpack tars switched to tar-fs from node-tar to unpack tars Mar 3, 2017
@bestander
Copy link
Member Author

@arcanis, could you review this please?

.pipe(tarFs.extract(destination, {
strip: 1,
dmode: parseInt(555, 8), // all dirs should be readable
fmode: parseInt(444, 8), // all files should be readable
Copy link
Member

Choose a reason for hiding this comment

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

0o555 and 0o444 ?

Copy link
Member Author

Choose a reason for hiding this comment

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

👍

Copy link
Member

Choose a reason for hiding this comment

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

Just noticed - you forgot this instance :)

const untarStream = tar.Extract({path: this.dest});
const untarStream = tarFs.extract(this.dest, {
dmode: parseInt(555, 8), // all dirs should be readable
fmode: parseInt(444, 8), // all files should be readable
Copy link
Member

Choose a reason for hiding this comment

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

Same

const untarStream = tarFs.extract(this.dest, {
strip: 1,
dmode: parseInt(555, 8), // all dirs should be readable
fmode: parseInt(444, 8), // all files should be readable
Copy link
Member

Choose a reason for hiding this comment

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

Same - shouldn't the unpack routine be splitted into an helper, since it used in a few places?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sometimes we need to strip first folder, sometimes not.
And moving dmode,fbmode into a separate function looks like an overkill

Copy link
Member

Choose a reason for hiding this comment

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

👍

src/util/git.js Outdated
parser.on('entry', (header, stream, next) => {
let string = '';
stream.on('data', (buffer) => {
string += buffer.toString();
Copy link
Member

Choose a reason for hiding this comment

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

iirc, this pattern might break when the buffer contains part of an unicode character but not the others. It might be better to concat the buffers together (possibly by storing them in a list and then concatenating everything at once with Buffer.concat) rather than concatenating strings.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, smart!
I'll do that

src/util/git.js Outdated
const extractor = tar.Extract({path: dest});
const extractor = tarFs.extract(dest, {
dmode: parseInt(555, 8), // all dirs should be readable
fmode: parseInt(444, 8), // all files should be readable
Copy link
Member

Choose a reason for hiding this comment

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

Same

src/util/git.js Outdated
const extractor = tar.Extract({path: dest});
const extractor = tarFs.extract(dest, {
dmode: parseInt(555, 8), // all dirs should be readable
fmode: parseInt(444, 8), // all files should be readable
Copy link
Member

Choose a reason for hiding this comment

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

@bestander
Copy link
Member Author

ping @arcanis, ready for another round

src/util/git.js Outdated
stream.on('end', () => {
update(string);
fileContent += decoder.end();
update(fileContent);
Copy link
Member

Choose a reason for hiding this comment

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

Since it isn't really used anymore, maybe fileContent should be removed completely, using update(decoded.end()) instead

Copy link
Member Author

Choose a reason for hiding this comment

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

decoded.end() won't return a full string.
It would just return remaining bytes if there were any.
So I needed to accumulate them in a string

Copy link
Member

Choose a reason for hiding this comment

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

Oh I see, my bad ! I initially thought the decoder was holding the whole buffer 👍

@victornoel
Copy link
Contributor

@bestander it could make sense to also use gunzip-maybe (like tar-fs, it is by @mafintosh) instead of reimplementing it in utils/stream.

BYK added a commit that referenced this pull request Sep 4, 2017
**Summary**

Fixes: #992. This issue was supposed to be fixed by #2826 but it
was not setting directory permissions wide enough. This patch uses
the `readable` and `writable` options provided by the `tar-fs`
package which essentially sets everything to `0o777`.

**Test plan**

N/A
arcanis pushed a commit that referenced this pull request Sep 4, 2017
* Fix: make sure all extracted tarballs are r/w enabled

**Summary**

Fixes: #992. This issue was supposed to be fixed by #2826 but it
was not setting directory permissions wide enough. This patch uses
the `readable` and `writable` options provided by the `tar-fs`
package which essentially sets everything to `0o777`.

**Test plan**

N/A

* fewer perms
joaolucasl pushed a commit to joaolucasl/yarn that referenced this pull request Oct 27, 2017
* Fix: make sure all extracted tarballs are r/w enabled

**Summary**

Fixes: yarnpkg#992. This issue was supposed to be fixed by yarnpkg#2826 but it
was not setting directory permissions wide enough. This patch uses
the `readable` and `writable` options provided by the `tar-fs`
package which essentially sets everything to `0o777`.

**Test plan**

N/A

* fewer perms
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.

Yarn should normalize permissions when untarring packages.

3 participants