Skip to content

Commit

Permalink
Turbopack: fix graph chunk groups (#76383)
Browse files Browse the repository at this point in the history
### What?

* Fix pages graph entrypoints
* Fix chunk_group_info computation for merged
* Fix client_shared_entries in graph
* chunk_group_info: continue walking across graphs
  • Loading branch information
sokra authored Feb 24, 2025
1 parent 0f47638 commit 5d1eced
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 29 deletions.
28 changes: 16 additions & 12 deletions crates/next-api/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,13 +813,14 @@ impl AppProject {
&self,
endpoint: Vc<AppEndpoint>,
rsc_entry: ResolvedVc<Box<dyn Module>>,
extra_entries: Vc<EvaluatableAssets>,
client_shared_entries: Vc<EvaluatableAssets>,
has_layout_segments: bool,
) -> Result<Vc<ModuleGraphs>> {
let extra_entries = extra_entries
let client_shared_entries = client_shared_entries
.await?
.into_iter()
.map(|m| ResolvedVc::upcast(*m));
.map(|m| ResolvedVc::upcast(*m))
.collect();

if *self.project.per_page_module_graph().await? {
// Implements layout segment optimization to compute a graph "chain" for each layout
Expand All @@ -833,14 +834,17 @@ impl AppProject {
} = &*find_server_entries(*rsc_entry).await?;

let graph = SingleModuleGraph::new_with_entries_visited(
vec![(
server_utils
.iter()
.map(|m| ResolvedVc::upcast(*m))
.chain(extra_entries)
.collect(),
ChunkGroupType::Entry,
)],
vec![
(
server_utils
.iter()
.map(async |m| Ok(ResolvedVc::upcast(m.await?.module)))
.try_join()
.await?,
ChunkGroupType::Entry,
),
(client_shared_entries, ChunkGroupType::Evaluated),
],
VisitedModules::empty(),
);
graphs.push(graph);
Expand Down Expand Up @@ -869,7 +873,7 @@ impl AppProject {
visited_modules
} else {
let graph = SingleModuleGraph::new_with_entries_visited(
vec![(extra_entries.collect(), ChunkGroupType::Entry)],
vec![(client_shared_entries, ChunkGroupType::Evaluated)],
VisitedModules::empty(),
);
graphs.push(graph);
Expand Down
6 changes: 5 additions & 1 deletion crates/next-api/src/pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1475,7 +1475,11 @@ impl Endpoint for PageEndpoint {

if let PageEndpointType::Html = this.ty {
modules.push((
vec![self.client_module().to_resolved().await?],
self.client_evaluatable_assets()
.await?
.iter()
.map(|m| ResolvedVc::upcast(*m))
.collect(),
ChunkGroupType::Evaluated,
));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use crate::{
chunk::{ChunkGroupType, ChunkingType},
module::Module,
module_graph::{
get_node, GraphNodeIndex, GraphTraversalAction, ModuleGraph, SingleModuleGraphModuleNode,
SingleModuleGraphNode,
get_node, get_node_idx, GraphNodeIndex, GraphTraversalAction, ModuleGraph,
SingleModuleGraphModuleNode, SingleModuleGraphNode,
},
};

Expand Down Expand Up @@ -152,14 +152,14 @@ enum ChunkGroupKey {
},
/// a module with an incoming async edge
Async(ResolvedVc<Box<dyn Module>>),
/// a module with an incoming non-merged isolated edge
/// a module with an incoming non-merging isolated edge
Isolated(ResolvedVc<Box<dyn Module>>),
/// a module with an incoming merging isolated edge
IsolatedMerged {
parent: ChunkGroupId,
merge_tag: RcStr,
},
/// a module with an incoming merging shared edge
/// a module with an incoming non-merging shared edge
Shared(ResolvedVc<Box<dyn Module>>),
/// a module with an incoming merging shared edge
SharedMerged {
Expand Down Expand Up @@ -353,20 +353,23 @@ pub async fn compute_chunk_group_info(graph: &ModuleGraph) -> Result<Vc<ChunkGro
// Start of a new chunk group, don't inherit anything from parent
let chunk_group_ids = chunk_groups.map(|chunk_group| {
let len = chunk_groups_map.len();
let is_isolated_merged =
matches!(chunk_group, ChunkGroupKey::IsolatedMerged { .. });
let is_merged = matches!(
chunk_group,
ChunkGroupKey::IsolatedMerged { .. }
| ChunkGroupKey::SharedMerged { .. }
);
match chunk_groups_map.entry(chunk_group) {
Entry::Occupied(mut e) => {
let (id, isolated_merged_entries) = e.get_mut();
if is_isolated_merged {
isolated_merged_entries.insert(node.module);
let (id, merged_entries) = e.get_mut();
if is_merged {
merged_entries.insert(node.module);
}
**id
}
Entry::Vacant(e) => {
let chunk_group_id = len as u32;
let mut set = FxIndexSet::default();
if is_isolated_merged {
if is_merged {
set.insert(node.module);
}
e.insert((ChunkGroupId(chunk_group_id), set));
Expand Down Expand Up @@ -443,8 +446,8 @@ pub async fn compute_chunk_group_info(graph: &ModuleGraph) -> Result<Vc<ChunkGro
}
while let Some(NodeWithPriority { node, .. }) = queue.pop() {
queue_set.remove(&node);
let (node_weight, node) = get_node_idx!(graphs, node)?;
let graph = &graphs[node.graph_idx].graph;
let node_weight = get_node!(graphs, node)?;
let neighbors = iter_neighbors(graph, node.node_idx);

visit_count += 1;
Expand All @@ -454,7 +457,7 @@ pub async fn compute_chunk_group_info(graph: &ModuleGraph) -> Result<Vc<ChunkGro
graph_idx: node.graph_idx,
node_idx: succ,
};
let succ_weight = get_node!(graphs, succ)?;
let (succ_weight, succ) = get_node_idx!(graphs, succ)?;
let edge_weight = graph.edge_weight(edge).unwrap();
let action = visitor(
Some((node_weight, edge_weight)),
Expand Down Expand Up @@ -483,22 +486,22 @@ pub async fn compute_chunk_group_info(graph: &ModuleGraph) -> Result<Vc<ChunkGro
module_chunk_groups,
chunk_groups: chunk_groups_map
.into_iter()
.map(|(k, (_, isolated_merged_entries))| match k {
.map(|(k, (_, merged_entries))| match k {
ChunkGroupKey::Entry { entries, ty } => ChunkGroup::Entry { entries, ty },
ChunkGroupKey::Async(module) => ChunkGroup::Async(module),
ChunkGroupKey::Isolated(module) => ChunkGroup::Isolated(module),
ChunkGroupKey::IsolatedMerged { parent, merge_tag } => {
ChunkGroup::IsolatedMerged {
parent: parent.0 as usize,
merge_tag,
entries: isolated_merged_entries.into_iter().collect(),
entries: merged_entries.into_iter().collect(),
}
}
ChunkGroupKey::Shared(module) => ChunkGroup::Shared(module),
ChunkGroupKey::SharedMerged { parent, merge_tag } => ChunkGroup::SharedMerged {
parent: parent.0 as usize,
merge_tag,
entries: isolated_merged_entries.into_iter().collect(),
entries: merged_entries.into_iter().collect(),
},
})
.collect(),
Expand Down
24 changes: 23 additions & 1 deletion turbopack/crates/turbopack-core/src/module_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ macro_rules! get_node {
Some(SingleModuleGraphNode::Module(node)) => ::anyhow::Ok(node),
Some(SingleModuleGraphNode::VisitedModule { idx, .. }) => {
match $graphs[idx.graph_idx].graph.node_weight(idx.node_idx) {
Some(SingleModuleGraphNode::Module(node)) => anyhow::Ok(node),
Some(SingleModuleGraphNode::Module(node)) => ::anyhow::Ok(node),
Some(SingleModuleGraphNode::VisitedModule { .. }) => Err(::anyhow::anyhow!(
"Expected visited target node to be module"
)),
Expand All @@ -704,6 +704,28 @@ macro_rules! get_node {
}};
}
pub(crate) use get_node;
macro_rules! get_node_idx {
($graphs:expr, $node:expr) => {{
let node_idx = $node;
match $graphs[node_idx.graph_idx]
.graph
.node_weight(node_idx.node_idx)
{
Some(SingleModuleGraphNode::Module(node)) => ::anyhow::Ok((node, node_idx)),
Some(SingleModuleGraphNode::VisitedModule { idx, .. }) => {
match $graphs[idx.graph_idx].graph.node_weight(idx.node_idx) {
Some(SingleModuleGraphNode::Module(node)) => ::anyhow::Ok((node, *idx)),
Some(SingleModuleGraphNode::VisitedModule { .. }) => Err(::anyhow::anyhow!(
"Expected visited target node to be module"
)),
None => Err(::anyhow::anyhow!("Expected visited target node")),
}
}
None => Err(::anyhow::anyhow!("Expected graph node")),
}
}};
}
pub(crate) use get_node_idx;

// pub struct AllNodesIterator {
// inner: Vec<ReadRef<SingleModuleGraph>>,
Expand Down

0 comments on commit 5d1eced

Please sign in to comment.