Skip to content

Commit

Permalink
Fixed the cycle error bug
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael-F-Bryan committed Jun 8, 2023
1 parent 13c3ba6 commit abb0631
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 24 deletions.
46 changes: 23 additions & 23 deletions lib/wasix/src/runtime/resolver/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,7 @@ async fn discover_dependencies(
}
}

let sorted_indices =
dbg!(petgraph::algo::toposort(&graph, None)).map_err(|cycle| cycle_error(&graph, cycle))?;
dbg!(sorted_indices
.iter()
.copied()
.map(|ix| &graph[ix].id)
.collect::<Vec<_>>());
let sorted_indices = petgraph::algo::toposort(&graph, None).map_err(|_| cycle_error(&graph))?;

Ok(DiscoveredPackages {
root: root_index,
Expand All @@ -174,24 +168,30 @@ async fn discover_dependencies(
})
}

fn cycle_error(
graph: &petgraph::Graph<Node, Edge>,
cycle: petgraph::algo::Cycle<NodeIndex>,
) -> ResolveError {
eprintln!(
"{}",
petgraph::dot::Dot::new(
&graph.map(|_, node| node.id.to_string(), |_, edge| edge.alias.clone()),
)
);
let cyclic_node = cycle.node_id();
let cycle: Vec<_> =
petgraph::algo::simple_paths::all_simple_paths(graph, cyclic_node, cyclic_node, 1, None)
.next()
.expect("We know there is at least one cycle");
fn cycle_error(graph: &petgraph::Graph<Node, Edge>) -> ResolveError {
// We know the graph has at least one cycle, so use SCC to find it.
let mut cycle = petgraph::algo::kosaraju_scc(graph)
.into_iter()
.find(|cycle| cycle.len() > 1)
.expect("We know there is at least one cycle");

// we want the loop's starting node to be deterministic (for tests), and
// nodes with lower indices are normally closer to the root of the
// dependency tree.
let lowest_index_node = cycle.iter().copied().min().expect("Cycle is non-empty");

// We want the cycle vector to start with that node, so let's do a bit of
// shuffling
let offset = cycle
.iter()
.position(|&node| node == lowest_index_node)
.unwrap();
cycle.rotate_left(offset);

let package_ids = cycle.into_iter().map(|ix| graph[ix].pkg.id()).collect();
// Don't forget to make the cycle start and end with the same node
cycle.push(lowest_index_node);

let package_ids = cycle.into_iter().map(|ix| graph[ix].pkg.id()).collect();
ResolveError::Cycle(package_ids)
}

Expand Down
2 changes: 1 addition & 1 deletion lib/wasix/src/runtime/resolver/wapm_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ mod tests {

use crate::{
http::HttpResponse,
runtime::resolver::inputs::{DistributionInfo, PackageInfo, FileSystemMapping},
runtime::resolver::inputs::{DistributionInfo, FileSystemMapping, PackageInfo},
};

use super::*;
Expand Down

0 comments on commit abb0631

Please sign in to comment.