Skip to content

Commit

Permalink
Stop using Future.wait in build_impl.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmorgan committed Mar 3, 2025
1 parent a49bbef commit 1045f3a
Showing 1 changed file with 73 additions and 80 deletions.
153 changes: 73 additions & 80 deletions build_runner_core/lib/src/generate/build_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -398,34 +398,32 @@ class _SingleBuild {
var phase = _buildPhases[phaseNumber];
var packageNode = _packageGraph[package]!;

await Future.wait(
_assetGraph.outputsForPhase(package, phaseNumber).map((node) async {
if (!shouldBuildForDirs(
node.id,
buildDirs: _buildPaths(_buildDirs),
buildFilters: _buildFilters,
phase: phase,
targetGraph: _targetGraph,
)) {
return;
}
for (final node in _assetGraph.outputsForPhase(package, phaseNumber)) {
if (!shouldBuildForDirs(
node.id,
buildDirs: _buildPaths(_buildDirs),
buildFilters: _buildFilters,
phase: phase,
targetGraph: _targetGraph,
)) {
continue;
}

// Don't build for inputs that aren't visible. This can happen for
// placeholder nodes like `test/$test$` that are added to each package,
// since the test dir is not part of the build for non-root packages.
if (!_targetGraph.isVisibleInBuild(node.id, packageNode)) return;
// Don't build for inputs that aren't visible. This can happen for
// placeholder nodes like `test/$test$` that are added to each package,
// since the test dir is not part of the build for non-root packages.
if (!_targetGraph.isVisibleInBuild(node.id, packageNode)) continue;

var input = _assetGraph.get(node.primaryInput)!;
if (input is GeneratedAssetNode) {
if (input.state != NodeState.upToDate) {
await _runLazyPhaseForInput(input.phaseNumber, input.primaryInput);
}
if (!input.wasOutput) return;
if (input.isFailure) return;
var input = _assetGraph.get(node.primaryInput)!;
if (input is GeneratedAssetNode) {
if (input.state != NodeState.upToDate) {
await _runLazyPhaseForInput(input.phaseNumber, input.primaryInput);
}
ids.add(input.id);
}),
);
if (!input.wasOutput) continue;
if (input.isFailure) continue;
}
ids.add(input.id);
}
return ids;
}

Expand All @@ -439,13 +437,11 @@ class _SingleBuild {
InBuildPhase action,
Iterable<AssetId> primaryInputs,
) async {
var outputLists = await Future.wait(
primaryInputs.map((input) => _runForInput(phaseNumber, action, input)),
);
return outputLists.fold<List<AssetId>>(
<AssetId>[],
(combined, next) => combined..addAll(next),
);
final outputs = <AssetId>[];
for (final input in primaryInputs) {
outputs.addAll(await _runForInput(phaseNumber, action, input));
}
return outputs;
}

/// Lazily runs [phaseNumber] with [input]..
Expand Down Expand Up @@ -600,15 +596,13 @@ class _SingleBuild {
PostBuildPhase phase,
) async {
var actionNum = 0;
var outputLists = await Future.wait(
phase.builderActions.map(
(action) => _runPostProcessAction(phaseNum, actionNum++, action),
),
);
return outputLists.fold<List<AssetId>>(
<AssetId>[],
(combined, next) => combined..addAll(next),
);
final outputs = <AssetId>[];
for (final action in phase.builderActions) {
outputs.addAll(
await _runPostProcessAction(phaseNum, actionNum++, action),
);
}
return outputs;
}

Future<Iterable<AssetId>> _runPostProcessAction(
Expand All @@ -630,20 +624,18 @@ class _SingleBuild {
}
return false;
}).cast<PostProcessAnchorNode>();
var outputLists = await Future.wait(
anchorNodes.map(
(anchorNode) => _runPostProcessBuilderForAnchor(
final outputs = <AssetId>[];
for (final anchorNode in anchorNodes) {
outputs.addAll(
await _runPostProcessBuilderForAnchor(
phaseNum,
actionNum,
action.builder,
anchorNode,
),
),
);
return outputLists.fold<List<AssetId>>(
<AssetId>[],
(combined, next) => combined..addAll(next),
);
);
}
return outputs;
}

Future<Iterable<AssetId>> _runPostProcessBuilderForAnchor(
Expand Down Expand Up @@ -836,13 +828,14 @@ class _SingleBuild {
/// This should be called after deciding that an asset really needs to be
/// regenerated based on its inputs hash changing. All assets in [outputs]
/// must correspond to a [GeneratedAssetNode].
Future<void> _cleanUpStaleOutputs(Iterable<AssetId> outputs) => Future.wait(
outputs
.map(_assetGraph.get)
.cast<GeneratedAssetNode>()
.where((n) => n.wasOutput)
.map((n) => _delete(n.id)),
);
Future<void> _cleanUpStaleOutputs(Iterable<AssetId> outputs) async {
for (final output in outputs) {
final node = _assetGraph.get(output)!;
if (node is GeneratedAssetNode && node.wasOutput) {
await _delete(output);
}
}
}

Future<void> _buildGlobNode(GlobAssetNode globNode) async {
if (globNode.state == NodeState.upToDate) return;
Expand All @@ -860,9 +853,11 @@ class _SingleBuild {
.where((n) => globNode.glob.matches(n.id.path))
.toList();

await Future.wait(
potentialNodes.whereType<GeneratedAssetNode>().map(_buildAsset),
);
for (final node in potentialNodes) {
if (node is GeneratedAssetNode) {
await _buildAsset(node);
}
}

var actualMatches = <AssetId>[];
for (var node in potentialNodes) {
Expand Down Expand Up @@ -904,27 +899,25 @@ class _SingleBuild {

// Limit the total number of digests we are computing at a time. Otherwise
// this can overload the event queue.
await Future.wait(
ids.map((id) async {
var node = _assetGraph.get(id)!;
if (node is GlobAssetNode) {
await _buildGlobNode(node);
} else if (!await reader.canRead(id)) {
// We want to add something here, a missing/unreadable input should be
// different from no input at all.
//
// This needs to be unique per input so we use the md5 hash of the id.
combine(md5.convert(id.toString().codeUnits).bytes as Uint8List);
return;
} else {
if (node.lastKnownDigest == null) {
await reader.cache.invalidate([id]);
node.lastKnownDigest = await reader.digest(id);
}
for (final id in ids) {
var node = _assetGraph.get(id)!;
if (node is GlobAssetNode) {
await _buildGlobNode(node);
} else if (!await reader.canRead(id)) {
// We want to add something here, a missing/unreadable input should be
// different from no input at all.
//
// This needs to be unique per input so we use the md5 hash of the id.
combine(md5.convert(id.toString().codeUnits).bytes as Uint8List);
continue;
} else {
if (node.lastKnownDigest == null) {
await reader.cache.invalidate([id]);
node.lastKnownDigest = await reader.digest(id);
}
combine(node.lastKnownDigest!.bytes as Uint8List);
}),
);
}
combine(node.lastKnownDigest!.bytes as Uint8List);
}

return Digest(combinedBytes);
}
Expand Down

0 comments on commit 1045f3a

Please sign in to comment.