Skip to content

Commit 062993b

Browse files
Refactor request tracker following PR feedback (#9755)
Co-authored-by: pyamada (Remote Dev Environment) <[email protected]>
1 parent e67a957 commit 062993b

File tree

8 files changed

+111
-74
lines changed

8 files changed

+111
-74
lines changed

crates/parcel_config/src/parcel_rc_config_loader.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,8 @@ impl ParcelRcConfigLoader {
4242
fn find_config(&self, project_root: &Path, path: &PathBuf) -> Result<PathBuf, ConfigError> {
4343
let from = path.parent().unwrap_or(path);
4444

45-
find_ancestor_file(
46-
Rc::clone(&self.fs),
47-
vec![String::from(".parcelrc")],
48-
from,
49-
project_root,
50-
)
51-
.ok_or(ConfigError::MissingParcelRc(PathBuf::from(from)))
45+
find_ancestor_file(&*self.fs, &[".parcelrc"], from, project_root)
46+
.ok_or(ConfigError::MissingParcelRc(PathBuf::from(from)))
5247
}
5348

5449
fn resolve_from(&self, project_root: &PathBuf) -> PathBuf {

crates/parcel_core/src/plugin/plugin_config.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ impl PluginConfig {
2929
filename: &str,
3030
) -> Result<(PathBuf, Config), anyhow::Error> {
3131
let config_path = find_ancestor_file(
32-
Rc::clone(&self.fs),
33-
vec![String::from(filename)],
32+
&*self.fs,
33+
&[filename],
3434
&self.search_path,
3535
&self.project_root,
3636
)

crates/parcel_core/src/request_tracker/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ mod request_graph;
33
mod request_tracker;
44

55
#[cfg(test)]
6-
mod _test;
6+
mod test;
77

88
pub use self::request::*;
99
pub use self::request_graph::*;

crates/parcel_core/src/request_tracker/request.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,33 @@ use dyn_hash::DynHash;
77

88
use super::RequestTracker;
99

10+
pub struct RunRequestContext<'a, T> {
11+
parent_request_hash: Option<u64>,
12+
request_tracker: &'a mut RequestTracker<T>,
13+
}
14+
15+
impl<'a, T: Clone> RunRequestContext<'a, T> {
16+
pub(crate) fn new(
17+
parent_request_hash: Option<u64>,
18+
request_tracker: &'a mut RequestTracker<T>,
19+
) -> Self {
20+
Self {
21+
parent_request_hash,
22+
request_tracker,
23+
}
24+
}
25+
26+
// TODO: Why is this boxed?
27+
pub fn run_request(&mut self, request: Box<&dyn Request<T>>) -> anyhow::Result<T> {
28+
self
29+
.request_tracker
30+
.run_child_request(request, self.parent_request_hash)
31+
}
32+
}
33+
34+
// We can type this properly
35+
pub type RunRequestError = anyhow::Error;
36+
1037
pub trait Request<T: Clone>: DynHash {
1138
fn id(&self) -> u64 {
1239
let mut hasher = DefaultHasher::default();
@@ -15,7 +42,8 @@ pub trait Request<T: Clone>: DynHash {
1542
hasher.finish()
1643
}
1744

18-
fn run(&self, request_tracker: RequestTracker<T>) -> Result<RequestResult<T>, Vec<RequestError>>;
45+
fn run(&self, request_tracker: RunRequestContext<T>)
46+
-> Result<RequestResult<T>, RunRequestError>;
1947
}
2048

2149
dyn_hash::hash_trait_object!(<T: Clone> Request<T>);

crates/parcel_core/src/request_tracker/request_graph.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use petgraph::stable_graph::StableDiGraph;
22

3-
use super::RequestError;
3+
use super::RunRequestError;
44

55
pub type RequestGraph<T> = StableDiGraph<RequestNode<T>, RequestEdgeType>;
66

77
#[derive(Debug)]
88
pub enum RequestNode<T> {
9-
Error(Vec<RequestError>),
9+
Error(RunRequestError),
1010
Root,
1111
Incomplete,
1212
Valid(T),

crates/parcel_core/src/request_tracker/request_tracker.rs

+65-50
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,128 @@
1-
use std::cell::RefCell;
1+
use anyhow::anyhow;
22
use std::collections::HashMap;
3-
use std::rc::Rc;
43

54
use petgraph::graph::NodeIndex;
65
use petgraph::stable_graph::StableDiGraph;
76

8-
use super::Request;
97
use super::RequestEdgeType;
10-
use super::RequestError;
118
use super::RequestGraph;
129
use super::RequestNode;
1310
use super::RequestResult;
11+
use super::{Request, RunRequestContext, RunRequestError};
1412

15-
#[derive(Clone)]
16-
pub struct RequestTracker<T: Clone> {
17-
parent_request_hash: Option<u64>,
18-
graph: Rc<RefCell<RequestGraph<T>>>,
19-
request_index: Rc<RefCell<HashMap<u64, NodeIndex>>>,
13+
pub struct RequestTracker<T> {
14+
graph: RequestGraph<T>,
15+
request_index: HashMap<u64, NodeIndex>,
2016
}
2117

2218
impl<T: Clone> RequestTracker<T> {
2319
pub fn new() -> Self {
2420
let mut graph = StableDiGraph::<RequestNode<T>, RequestEdgeType>::new();
2521
graph.add_node(RequestNode::Root);
2622
RequestTracker {
27-
parent_request_hash: None,
28-
graph: Rc::new(RefCell::new(graph)),
29-
request_index: Rc::new(RefCell::new(HashMap::new())),
23+
graph,
24+
request_index: HashMap::new(),
3025
}
3126
}
3227

33-
pub fn run_request(&self, request: Box<&dyn Request<T>>) -> Result<T, Vec<RequestError>> {
28+
pub fn run_request(&mut self, request: Box<&dyn Request<T>>) -> anyhow::Result<T> {
29+
self.run_child_request(request, None)
30+
}
31+
32+
pub fn run_child_request(
33+
&mut self,
34+
request: Box<&dyn Request<T>>,
35+
parent_request_hash: Option<u64>,
36+
) -> anyhow::Result<T> {
3437
let request_id = request.id();
3538

36-
if self.prepare_request(request_id.clone()) {
37-
let mut rt = self.clone();
38-
rt.parent_request_hash.replace(request_id.clone());
39-
self.store_request(&request_id, request.run(rt));
39+
if self.prepare_request(request_id.clone())? {
40+
let result = request.run(RunRequestContext::new(Some(request_id), self));
41+
self.store_request(&request_id, result)?;
4042
}
4143

42-
self.get_request(&request_id)
44+
Ok(self.get_request(parent_request_hash, &request_id)?)
4345
}
4446

45-
fn prepare_request(&self, request_id: u64) -> bool {
46-
let mut graph = self.graph.borrow_mut();
47-
let mut request_index = self.request_index.borrow_mut();
48-
49-
let node_index = request_index
47+
fn prepare_request(&mut self, request_id: u64) -> anyhow::Result<bool> {
48+
let node_index = self
49+
.request_index
5050
.entry(request_id)
51-
.or_insert_with(|| graph.add_node(RequestNode::Incomplete));
51+
.or_insert_with(|| self.graph.add_node(RequestNode::Incomplete));
5252

53-
let request_node = graph.node_weight_mut(*node_index).unwrap();
53+
let request_node = self
54+
.graph
55+
.node_weight_mut(*node_index)
56+
.ok_or_else(|| anyhow!("Failed to find request node"))?;
5457

5558
// Don't run if already run
5659
if let RequestNode::<T>::Valid(_) = request_node {
57-
return false;
60+
return Ok(false);
5861
}
5962

6063
*request_node = RequestNode::Incomplete;
61-
true
64+
Ok(true)
6265
}
6366

64-
fn store_request(&self, request_id: &u64, result: Result<RequestResult<T>, Vec<RequestError>>) {
65-
let request_index = self.request_index.borrow();
66-
let mut graph = self.graph.borrow_mut();
67-
68-
let node_index = request_index.get(&request_id).unwrap();
69-
70-
let request_node = graph.node_weight_mut(*node_index).unwrap();
67+
fn store_request(
68+
&mut self,
69+
request_id: &u64,
70+
result: Result<RequestResult<T>, RunRequestError>,
71+
) -> anyhow::Result<()> {
72+
let node_index = self
73+
.request_index
74+
.get(&request_id)
75+
.ok_or_else(|| anyhow!("Failed to find request"))?;
76+
let request_node = self
77+
.graph
78+
.node_weight_mut(*node_index)
79+
.ok_or_else(|| anyhow!("Failed to find request"))?;
7180
if let RequestNode::<T>::Valid(_) = request_node {
72-
return;
81+
return Ok(());
7382
}
7483
*request_node = match result {
7584
Ok(result) => RequestNode::Valid(result.result),
7685
Err(error) => RequestNode::Error(error),
7786
};
78-
}
7987

80-
fn get_request(&self, request_id: &u64) -> Result<T, Vec<RequestError>> {
81-
let mut graph = self.graph.borrow_mut();
82-
let request_index = self.request_index.borrow();
88+
Ok(())
89+
}
8390

84-
let Some(node_index) = request_index.get(&request_id) else {
85-
return Err(vec![RequestError::Impossible]);
91+
fn get_request(
92+
&mut self,
93+
parent_request_hash: Option<u64>,
94+
request_id: &u64,
95+
) -> anyhow::Result<T> {
96+
let Some(node_index) = self.request_index.get(&request_id) else {
97+
return Err(anyhow!("Impossible error"));
8698
};
8799

88-
if let Some(parent_request_id) = self.parent_request_hash {
89-
let parent_node_index = request_index.get(&parent_request_id).unwrap();
90-
graph.add_edge(
100+
if let Some(parent_request_id) = parent_request_hash {
101+
let parent_node_index = self
102+
.request_index
103+
.get(&parent_request_id)
104+
.ok_or_else(|| anyhow!("Failed to find requests"))?;
105+
self.graph.add_edge(
91106
parent_node_index.clone(),
92107
node_index.clone(),
93108
RequestEdgeType::SubRequest,
94109
);
95110
} else {
96-
graph.add_edge(
111+
self.graph.add_edge(
97112
NodeIndex::new(0),
98113
node_index.clone(),
99114
RequestEdgeType::SubRequest,
100115
);
101116
}
102117

103-
let Some(request_node) = graph.node_weight(node_index.clone()) else {
104-
return Err(vec![RequestError::Impossible]);
118+
let Some(request_node) = self.graph.node_weight(node_index.clone()) else {
119+
return Err(anyhow!("Impossible"));
105120
};
106121

107122
match request_node {
108-
RequestNode::Root => Err(vec![RequestError::Impossible]),
109-
RequestNode::Incomplete => Err(vec![RequestError::Impossible]),
110-
RequestNode::Error(errors) => Err(errors.to_owned()),
123+
RequestNode::Root => Err(anyhow!("Impossible")),
124+
RequestNode::Incomplete => Err(anyhow!("Impossible")),
125+
RequestNode::Error(_errors) => Err(anyhow!("Impossible")),
111126
RequestNode::Valid(value) => Ok(value.clone()),
112127
}
113128
}

crates/parcel_core/src/request_tracker/_test.rs crates/parcel_core/src/request_tracker/test.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use super::*;
77

88
#[test]
99
fn should_run_request() {
10-
let rt = RequestTracker::<Vec<String>>::new();
10+
let mut rt = RequestTracker::<Vec<String>>::new();
1111

1212
let request_c = TestRequest::new("C", &[]);
1313
let request_b = TestRequest::new("B", &[&request_c]);
@@ -22,7 +22,7 @@ fn should_run_request() {
2222

2323
#[test]
2424
fn should_reuse_previously_run_request() {
25-
let rt = RequestTracker::<Vec<String>>::new();
25+
let mut rt = RequestTracker::<Vec<String>>::new();
2626

2727
let request_c = TestRequest::new("C", &[]);
2828
let request_b = TestRequest::new("B", &[&request_c]);
@@ -42,7 +42,7 @@ fn should_reuse_previously_run_request() {
4242

4343
#[test]
4444
fn should_run_request_once() {
45-
let rt = RequestTracker::<Vec<String>>::new();
45+
let mut rt = RequestTracker::<Vec<String>>::new();
4646

4747
let request_a = TestRequest::new("A", &[]);
4848

@@ -58,7 +58,7 @@ fn should_run_request_once() {
5858

5959
#[test]
6060
fn should_run_request_once_2() {
61-
let rt = RequestTracker::<Vec<String>>::new();
61+
let mut rt = RequestTracker::<Vec<String>>::new();
6262

6363
let request_b = TestRequest::new("B", &[]);
6464
let request_a = TestRequest::new("A", &[&request_b]);
@@ -116,8 +116,8 @@ impl<'a> std::hash::Hash for TestRequest<'a> {
116116
impl<'a> Request<Vec<String>> for TestRequest<'a> {
117117
fn run(
118118
&self,
119-
rt: RequestTracker<Vec<String>>,
120-
) -> Result<RequestResult<Vec<String>>, Vec<RequestError>> {
119+
mut context: RunRequestContext<Vec<String>>,
120+
) -> Result<RequestResult<Vec<String>>, RunRequestError> {
121121
self.runs.fetch_add(1, Ordering::Relaxed);
122122

123123
let name = self.name.clone();
@@ -127,7 +127,7 @@ impl<'a> Request<Vec<String>> for TestRequest<'a> {
127127

128128
while let Some(subrequest) = subrequets.pop() {
129129
let req = subrequest.clone();
130-
let subrequest_result = rt.run_request(Box::new(&req))?;
130+
let subrequest_result = context.run_request(Box::new(&req))?;
131131
result.extend(subrequest_result);
132132
}
133133

crates/parcel_filesystem/src/search.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use std::path::Path;
22
use std::path::PathBuf;
3-
use std::rc::Rc;
43

54
use crate::FileSystem;
65

76
pub fn find_ancestor_file<P: AsRef<Path>>(
8-
fs: Rc<dyn FileSystem>,
9-
filenames: Vec<String>,
7+
fs: &dyn FileSystem,
8+
filenames: &[&str],
109
from: P,
1110
root: P,
1211
) -> Option<PathBuf> {
@@ -18,7 +17,7 @@ pub fn find_ancestor_file<P: AsRef<Path>>(
1817
}
1918
}
2019

21-
for name in &filenames {
20+
for name in filenames {
2221
let fullpath = dir.join(name);
2322
if fs.is_file(&fullpath) {
2423
return Some(fullpath);

0 commit comments

Comments
 (0)