Skip to content
This repository has been archived by the owner on Aug 17, 2019. It is now read-only.

feat(optional): ignore failed optional deps #27

Merged
merged 1 commit into from
Oct 12, 2017
Merged

Conversation

zkat
Copy link
Owner

@zkat zkat commented Oct 10, 2017

Fixes: #3

@zkat zkat force-pushed the zkat/optional-fail branch 3 times, most recently from 4bf6684 to da76503 Compare October 11, 2017 09:04
@zkat zkat requested a review from mikesherov October 11, 2017 09:06
@zkat zkat changed the title wip: ignore failed optional deps feat(optional): ignore failed optional deps Oct 11, 2017
@zkat zkat force-pushed the zkat/optional-fail branch 2 times, most recently from 19e3a08 to f93b3d6 Compare October 11, 2017 10:00
Copy link
Collaborator

@mikesherov mikesherov left a comment

Choose a reason for hiding this comment

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

Looking really great. I think we can get this to be a bit simpler and more efficient though, unless I’m missing something. Let me know!

index.js Outdated
for (let dep of tree.dependencies.values()) {
if (dep.seenByMark) { continue }
dep.seenByMark = true
if (!dep.optional || !dep.failed) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

At this point, shouldn’t the only failed deps be optional, otherwise they would have thrown in the extractTree phase before this?

Copy link
Owner Author

Choose a reason for hiding this comment

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

I can probably get rid of that dep.optional. I think it's an artifact of an experiment, and pretty much useless now.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems like the only piece of feedback to incorporate.

@@ -137,11 +138,58 @@ class Installer {
this.pkgCount++
return this
})
.catch(e => {
if (child.optional) {
this.pkgCount++
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we be incrementing pkgCount for optional deps?

Copy link
Collaborator

Choose a reason for hiding this comment

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

  • failed optional deps

Copy link
Collaborator

Choose a reason for hiding this comment

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

Nvm, I see it’s decremented later.

index.js Outdated
.catch(e => {
if (child.optional) {
this.pkgCount++
child.failed = true
Copy link
Collaborator

Choose a reason for hiding this comment

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

Rather than marking this as failed via a property, could you do a Set for failed here? I know that in the mark phase, you’re iterating over the top level dependencies only to find failed deps, so a Set doesn’t save much, but it’s something.

index.js Outdated
if (dep.seenByMark) { continue }
dep.seenByMark = true
if (!dep.optional || !dep.failed) {
liveDeps.add(dep)
Copy link
Collaborator

Choose a reason for hiding this comment

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

You may be able to eliminate this mark phase if you add to a failed Set instead of doing dep.failed during the extract phase...

index.js Outdated
if (dep.seenBySweep) { return }
dep.seenBySweep = true
return sweep(dep).then(() => {
if (!liveDeps.has(dep) && !dep.purged) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If there was a failed Set as suggested above, you could invert this conditional as if (failedDeps.has(dep))

Copy link
Owner Author

Choose a reason for hiding this comment

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

how would you mark transitive deps that didn't themselves fail?

index.js Outdated
dep.address.replace(/:/g, '/node_modules/')
)
installer.pkgCount--
dep.purged = true
Copy link
Collaborator

Choose a reason for hiding this comment

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

Rather than marking as purged, if there was a failed Set, you could remove it from the Set here, and not have to track purged at all, I think.

Copy link
Owner Author

Choose a reason for hiding this comment

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

We're doing a tree crawl through the whole thing anyway. This wouldn't really affect much.

@zkat
Copy link
Owner Author

zkat commented Oct 11, 2017

I responded in more detail on Discord but the tl;dr is that using a GC method makes it super easy to make sure we're purging unreachable transitive deps of failed optional deps, and taking into account that they might not be optional for others.

The performance impact of this GC is negligible at best: on the order of 10-20ms on a project with 2k+ deps

Copy link
Collaborator

@mikesherov mikesherov left a comment

Choose a reason for hiding this comment

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

Great work!

@zkat zkat merged commit a654629 into latest Oct 12, 2017
@zkat zkat deleted the zkat/optional-fail branch October 12, 2017 00:04
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.

None yet

2 participants