-
Notifications
You must be signed in to change notification settings - Fork 216
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
Memoization in Broccoli #396
Conversation
- Use callbackObject to get the plugins _revision count - Connect the watchRoot with the sane changed callback
@oligriffiths / @stefanpenner If you have some time could you both review this PR. I would like to discuss it at our Wednesday sync. The current status is still very much "work in progress". I just want to get your guy's input into the direction it is going and to talk about some of the "design" decisions I am making. |
- Renaming variables - Cleanup _revision work
following our chat https://gist.github.com/oligriffiths/ebff4a6947259e69aa970a6ac010acb2 |
@oligriffiths I sync'd with @stefanpenner after our talk and he brought up 2 good points that I don't believe we gave enough weight too:
I propose the following phases: Phase 1:
@oligriffiths has expressed a vision towards a Base class: class BroccoliPlugin {
shouldBuild() {
return this.inputs.hasChanges();
}
} Custom class: class MyPlugin extends BroccoliPlugin {
shouldBuild() {
if (Math.random() > .5) {
return false;
}
return true;
}
} Phase 2:
|
@thoov Yeah that makes sense. I think we could combine the two approaches and have the concept "revised" and output path be linked with a directory object. So rather than doing the file system diffing, expose So
or something. If we can decide on what the interface of the Directory facade should look like that solves the issue now, if we think that having an object to mediate file system stuff AND perform revision tracking, then we could just implement the revision tracking aspect right now and leave the file system stuff for later. Another thought: if a plugin opts into sideEffectFree, could we register a watcher for the output path and call |
Had some spare cycles so experimented with the above #397 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, left 1 question
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok this is looking great.
Couple of points.
We need to support 2 separate configuration options:
- Manual revision tracking - in stead of broccoli auto calling .revise() after each build, the plugin can opt-in to calling it manually
- Volatile plugins - regardless of any input node changes, always call build
It seems you are achieving this via the memoize
config option that can contain different values. I'm not sure this is the best API and I wonder if they should be separated out into separate options.
Second point, the name memorize
I'm not sure really says what is happening here. What you're doing is opting into manual change tracking.
I also think that unless you mark your plugin as "volatile" that we should call shouldBuild() before every build.
LMK your thoughts
Just had a chat with @oligriffiths, the summary of our chat was:
Given the above mentioned changes, we should 🚢. If you have concerns, or if we have missed something important, let's chat. But otherwise, we feel really good about this. |
👍 |
@lifeart the print out shows the slowest nodes so skipped nodes will almost never show as they have zero time. Which file did you make a change in to cause a rebuild and what else is in that tree? |
@lifeart / @oligriffiths Can we move this conversation to a new issue? Could we also clearly state what the problem is and how to reproduce in that issue? |
@thoov sure, I will try to create reproduction repo with latest ember and pined broccoli master. |
Background
Currently when a file change is detected broccoli will simply rebuild all of its nodes. Calling build can be expensive and results in nodes have to implement their own caching strategies (in best cases) or not caching (in worst cases). This PR "short circuits" the build chaining by enabling memoization (opt in via BROCCOLI_ENABLED_MEMOIZE=true) of nodes. This enables large amounts of the tree to no longer be rebuilt if broccoli detects that a nodes inputs have not changed (thus reducing rebuild times).
How does this work
_revision
that increments whenever their inputNodes have "changed"revise
on them whenever sane detects a change. For transform nodes,revise
is automatically called whenever its build method is called.volatile=true
as an option).Related PRs