-
Notifications
You must be signed in to change notification settings - Fork 212
Add to resolver_test
, add to AnalysisDriverModel
as needed to satisfy the tests.
#3822
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 to resolver_test
, add to AnalysisDriverModel
as needed to satisfy the tests.
#3822
Conversation
Package publishing
Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation. |
PR Health |
…isfy the tests. Run the tests with both "shared" instances, re-used between tests (as before) and "new" instances.
3700547
to
4f5f558
Compare
|
||
final content = await reader.readAsString(nextId); | ||
final deps = _parseDependencies(content, nextId); | ||
// Check for missing inputs that were written during the build. |
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.
I don't understand what a "missing input" is.
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.
Updated to
// Check for inputs that were missing when the directive graph was read
// but have since been written by another build action.
nextIds.add(dep); | ||
// Notify [buildStep] of its inputs. | ||
for (final id in inputIds) { | ||
await buildStep.canRead(id); |
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.
Does "canRead" say "this is what you should process" or does it say "this is what you are allowed to read" or how am I supposed to read the code in combination with the comment?
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.
Also possibly some were already "canRead" above (in if (transitive)
). Maybe this could be something like
if (transitive) {
// bla bla
for (final id in inputIds) {
// Notify [buildStep] of its inputs. And also other stuff.
if (await buildStep.canRead(id) && !id.path.endsWith(_transitiveDigestExtension) && _graph.nodes[id]!.isMissing) {
// Some good comment here.
idsToSyncOntoResourceProvider.add(id);
_syncedOntoResourceProvider.remove(id);
}
}
} else {
// Notify [buildStep] of its inputs.
for (final id in inputIds) {
await buildStep.canRead(id);
}
}
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.
canRead
asks the reader if the file is readable (exists + is allowed to be read), and marks the file as an input to the buildStep
. I need to untangle those two soon to make progress.
- notifying about inputs needs to be separate from reading; we can't efficiently track inputs while passing them around one by one
- there should be no need to eagerly check whether a file was written,
build_runner
can track which files get written
so I'll leave it separate as after those changes the reading and notifying will actually be separate :)
Thanks.
|
||
/// Walks the import graph from [ids] loading into [nodes]. | ||
Future<void> load(AssetReader reader, Iterable<AssetId> ids) async { | ||
final nextIds = Queue.of(ids); |
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.
I would have commented about this in one of the previous reviews as well but forgot.
Is there any reason this is a Queue instead of a List? A List should do removeLast
instead - so ordering would change -but otherwise I'd assume it was similar and probably perform better because it doesn't have to do casts and head and tail book keeping etc.
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.
No particular reason; but any cost here should be O(n)
, I want to solve the O(n^2)
issues before getting onto constant factor improvements ... added a TODO. Thanks.
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.
Thanks.
nextIds.add(dep); | ||
// Notify [buildStep] of its inputs. | ||
for (final id in inputIds) { | ||
await buildStep.canRead(id); |
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.
canRead
asks the reader if the file is readable (exists + is allowed to be read), and marks the file as an input to the buildStep
. I need to untangle those two soon to make progress.
- notifying about inputs needs to be separate from reading; we can't efficiently track inputs while passing them around one by one
- there should be no need to eagerly check whether a file was written,
build_runner
can track which files get written
so I'll leave it separate as after those changes the reading and notifying will actually be separate :)
Thanks.
|
||
final content = await reader.readAsString(nextId); | ||
final deps = _parseDependencies(content, nextId); | ||
// Check for missing inputs that were written during the build. |
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.
Updated to
// Check for inputs that were missing when the directive graph was read
// but have since been written by another build action.
|
||
/// Walks the import graph from [ids] loading into [nodes]. | ||
Future<void> load(AssetReader reader, Iterable<AssetId> ids) async { | ||
final nextIds = Queue.of(ids); |
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.
No particular reason; but any cost here should be O(n)
, I want to solve the O(n^2)
issues before getting onto constant factor improvements ... added a TODO. Thanks.
final nextId = nextIds.removeFirst(); | ||
|
||
// Skip if already seen. | ||
if (nodes.containsKey(nextId)) continue; |
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.
As far as I can tell you will run into trouble here - you may have previously put a _Node.missing
in for this node, and will not be able to resolve it later on.
This is a key driver of the performance issues - the fact that we have to be able to adapt to new files being added means we cannot (safely) cache globally the transitive deps.
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.
Note that even within a single build step you will run into this problem potentially, they are allowed to add new files which are imported by something they just resolved, and then resolve those files.
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.
Yes, probably new work is needed for files created during the build.
Missing files are currently checked again, but only to see if they now exist, the graph is not recomputed.
It passes all the tests, though :) so more tests are needed, too.
One question, is it the case that all files that are output by generators during the build are written by an AssetWriter
? Then, that should be a way to catch new files efficiently, rather than checking explicitly every time.
Thanks.
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.
Yes, all files will be written by an AssetWriter
. So, you may be able to add in some extra lifecycle hooks, but it starts getting into pretty dubious territory.
There is lots of weirdness because builders do not run in order most of the time, so you cannot rely on any phased ordering (instead they run when their output is requested). So, files go in and out of being "visible" depending on which builder happens to be running.
In order for a given input to have a consistent set of inputs, you have to do the crawl each time from each builder. We could possibly do something though where we accept that the inputs are over declared sometimes (a build step might pick up the transitive deps of a file it can't actually read).
Also, once you have been able to read a library you can cache its direct dependencies, which I believe the old system did do. So, you may still be able to do some of this.
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.
Makes sense, thanks. Anyway, next step, test coverage :)
For #3811
Run the tests with both "shared" instances, re-used between tests (as before) and "new" instances.
The new implementation is still not used, and is not finished: it's a further step towards adding tests / simplifying to understand what's going on and what can be done to improve performance.
This version does already save some time on the big builds :)
skip-changelog-check