Skip to content

Commit

Permalink
Forgot to add edges
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael-F-Bryan committed Jun 7, 2023
1 parent ef7191d commit 2c61c92
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 27 deletions.
8 changes: 6 additions & 2 deletions lib/wasi/src/runtime/resolver/in_memory_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ mod tests {
use tempfile::TempDir;

use crate::runtime::resolver::{
inputs::{DistributionInfo, PackageInfo},
inputs::{DistributionInfo, FileSystemMapping, PackageInfo},
Dependency, WebcHash,
};

Expand Down Expand Up @@ -168,7 +168,11 @@ mod tests {
name: "bash".to_string(),
}],
entrypoint: Some("bash".to_string()),
filesystem: Vec::new(),
filesystem: vec![FileSystemMapping {
volume_name: "atom".to_string(),
mount_path: "/".to_string(),
dependency_name: None,
}],
},
dist: DistributionInfo {
webc: crate::runtime::resolver::utils::url_from_file_path(
Expand Down
13 changes: 13 additions & 0 deletions lib/wasi/src/runtime/resolver/outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ impl DependencyGraph {
assert_eq!(*id, node.id, "Mismatch for node {index:?}");
}
}
debug_assert!(
packages.values().any(|ix| *ix == root),
"The packages mapping doesn't contain the root node"
);

DependencyGraph {
root,
Expand Down Expand Up @@ -111,6 +115,12 @@ impl DependencyGraph {
(id, dependencies)
})
}

/// Visualise this graph as a DOT program.
pub fn visualise(&self) -> String {
let graph = self.graph.map(|_, node| &node.id, |_, edge| &edge.alias);
petgraph::dot::Dot::new(&graph).to_string()
}
}

impl Index<NodeIndex> for DependencyGraph {
Expand Down Expand Up @@ -177,6 +187,9 @@ impl Eq for DependencyGraph {}
pub struct Node {
pub id: PackageId,
pub pkg: PackageInfo,
/// Information about how the package is distributed.
///
/// This will only ever be missing for the root package.
pub dist: Option<DistributionInfo>,
}

Expand Down
72 changes: 49 additions & 23 deletions lib/wasi/src/runtime/resolver/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ async fn discover_dependencies(
pkg: root.clone(),
dist: None,
});
nodes.insert(root_id.clone(), root_index);

let mut to_visit = VecDeque::new();
to_visit.push_back(root_index);

while let Some(index) = to_visit.pop_front() {
let mut deps = BTreeMap::new();

eprintln!("Checking {}", graph[index].id);
let mut to_add = Vec::new();

for dep in &graph[index].pkg.dependencies {
Expand All @@ -122,35 +122,49 @@ async fn discover_dependencies(
.latest(&dep.pkg)
.await
.map_err(ResolveError::Registry)?;
deps.insert(dep.alias().to_string(), dep_summary.package_id());
let dep_id = dep_summary.package_id();

if nodes.contains_key(&dep_id) {
// We don't need to visit this dependency again
continue;
}

// Otherwise, add it to the graph and schedule its dependencies to
// be retrieved

let PackageSummary { pkg, dist } = dep_summary;

to_add.push(Node {
let alias = dep.alias().to_string();
let node = Node {
id: dep_id,
pkg,
dist: Some(dist),
});
};
// Note: We can't add the node to the graph directly because we're
// still iterating over it.
to_add.push((alias, node));
}

for node in to_add {
let id = node.id.clone();
let index = graph.add_node(node);
nodes.insert(id, index);
for (alias, node) in to_add {
let dep_id = node.id.clone();
eprintln!("{} -> {} (as {alias})", &graph[index].id, dep_id);

let dep_index = match nodes.get(&dep_id) {
Some(&ix) => ix,
None => {
// Create a new node and schedule its dependencies to be
// retrieved
let ix = graph.add_node(node);
eprintln!("Scheduling to check \"{dep_id}\"");
nodes.insert(dep_id, ix);
to_visit.push_back(ix);
ix
}
};

graph.add_edge(index, dep_index, Edge { alias });
}
}

let sorted_indices =
petgraph::algo::toposort(&graph, None).map_err(|cycle| cycle_error(&graph, cycle))?;
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<_>>());

Ok(DiscoveredPackages {
root: root_index,
Expand All @@ -164,6 +178,12 @@ 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)
Expand Down Expand Up @@ -201,7 +221,7 @@ fn log_dependencies(graph: &DiGraph<Node, Edge>, root: NodeIndex) {
.map(|edge_ref| (&edge_ref.weight().alias, &graph[edge_ref.target()].id))
.collect();

tracing::trace!( %package, ?dependencies);
tracing::trace!(%package, ?dependencies);
}
});
}
Expand Down Expand Up @@ -324,6 +344,12 @@ fn resolve_package(dependency_graph: &DependencyGraph) -> Result<ResolvedPackage
}
}

// Note: when resolving filesystem mappings, the first mapping will come
// from the root package and its dependencies will be following. However, we
// actually want things closer to the root package in the dependency tree to
// come later so they override their dependencies.
filesystem.reverse();

Ok(ResolvedPackage {
root_package: dependency_graph.root_info().id(),
commands,
Expand Down Expand Up @@ -1072,14 +1098,14 @@ mod tests {
pkg.filesystem,
vec![
ResolvedFileSystemMapping {
mount_path: PathBuf::from("/usr/local/lib/second"),
mount_path: PathBuf::from("/usr/local/lib/first"),
volume_name: "main".to_string(),
package: builder.get("second", "1.0.0").package_id(),
package: builder.get("first", "1.0.0").package_id(),
},
ResolvedFileSystemMapping {
mount_path: PathBuf::from("/usr/local/lib/first"),
mount_path: PathBuf::from("/usr/local/lib/second"),
volume_name: "main".to_string(),
package: builder.get("first", "1.0.0").package_id(),
package: builder.get("second", "1.0.0").package_id(),
},
ResolvedFileSystemMapping {
mount_path: PathBuf::from("/root"),
Expand Down
8 changes: 6 additions & 2 deletions lib/wasi/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},
runtime::resolver::inputs::{DistributionInfo, PackageInfo, FileSystemMapping},
};

use super::*;
Expand Down Expand Up @@ -274,7 +274,11 @@ mod tests {
},
],
entrypoint: Some("wasmer-pack".to_string()),
filesystem: Vec::new(),
filesystem: vec![FileSystemMapping {
volume_name: "atom".to_string(),
mount_path: "/".to_string(),
dependency_name: None,
}],
},
dist: DistributionInfo {
webc: "https://registry-cdn.wapm.io/packages/wasmer/wasmer-pack-cli/wasmer-pack-cli-0.6.0-654a2ed8-875f-11ed-90e2-c6aeb50490de.webc".parse().unwrap(),
Expand Down

0 comments on commit 2c61c92

Please sign in to comment.