chore: clean up in preparation for release
This commit is contained in:
1 parent
c002161216
commit
827041c1b6
28 files changed
+112
-219
No files matched your search
+3
-2
@@ -18,7 +18,8 @@ categories = ["asynchronous", "concurrency", "data-structures"]
|
|||||||
exclude = [".claude/", ".jj/", "dagx-spec.md"]
|
exclude = [".claude/", ".jj/", "dagx-spec.md"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = ["derive"]
|
||||||
|
derive = ["dep:dagx-macros"]
|
||||||
tracing = ["dep:tracing"]
|
tracing = ["dep:tracing"]
|
||||||
|
|
||||||
[workspace.lints.rust]
|
[workspace.lints.rust]
|
||||||
@@ -32,7 +33,7 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
||||||
dagx-macros = { version = "0.3.1", path = "./dagx-macros" }
|
dagx-macros = { version = "0.3.1", path = "./dagx-macros", optional = true }
|
||||||
tracing = { version = "0.1", optional = true }
|
tracing = { version = "0.1", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pub fn bench_diamond_pattern(c: &mut Criterion) {
|
|||||||
.depends_on(a);
|
.depends_on(a);
|
||||||
let d = dag
|
let d = dag
|
||||||
.add_task(task_fn::<(i32, i32), _, _>(|(x, y): (&i32, &i32)| x + y))
|
.add_task(task_fn::<(i32, i32), _, _>(|(x, y): (&i32, &i32)| x + y))
|
||||||
.depends_on((&b, &c));
|
.depends_on((b, c));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pub fn bench_etl_pipeline(c: &mut Criterion) {
|
|||||||
result
|
result
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.depends_on((&transform1, &transform2, &transform3));
|
.depends_on((transform1, transform2, transform3));
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
let validate = dag
|
let validate = dag
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ pub fn bench_diamond(c: &mut Criterion) {
|
|||||||
.depends_on(source);
|
.depends_on(source);
|
||||||
|
|
||||||
dag.add_task(task_fn::<(i32, i32), _, _>(|(l, r): (&i32, &i32)| l + r))
|
dag.add_task(task_fn::<(i32, i32), _, _>(|(l, r): (&i32, &i32)| l + r))
|
||||||
.depends_on((&left, &right));
|
.depends_on((left, right));
|
||||||
}
|
}
|
||||||
|
|
||||||
let _output = dag
|
let _output = dag
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ pub fn bench_etl_pipeline(c: &mut Criterion) {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.depends_on((&validate, &scores, &names));
|
.depends_on((validate, scores, names));
|
||||||
|
|
||||||
let _output = dag
|
let _output = dag
|
||||||
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub fn bench_mixed_patterns(c: &mut Criterion) {
|
|||||||
format!("Matches: {}, Total bytes: {}, Count: {}", a1, a2, a3)
|
format!("Matches: {}, Total bytes: {}, Count: {}", a1, a2, a3)
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.depends_on((&analysis1, &analysis2, &analysis3));
|
.depends_on((analysis1, analysis2, analysis3));
|
||||||
|
|
||||||
// Stage 4: Fan-out final report to multiple destinations
|
// Stage 4: Fan-out final report to multiple destinations
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
|
|||||||
+7
-47
@@ -155,9 +155,10 @@ use syn::{parse_macro_input, FnArg, Ident, ImplItem, ItemImpl, Pat, PatType, Ret
|
|||||||
/// impl Task<(i32, i32)> for Add {
|
/// impl Task<(i32, i32)> for Add {
|
||||||
/// type Output = i32;
|
/// type Output = i32;
|
||||||
///
|
///
|
||||||
/// async fn run(&mut self, input: Self::Input) -> Self::Output {
|
/// async fn run(&mut self, _input: Self::Input) -> Self::Output {
|
||||||
/// let (a, b) = input;
|
/// let (a, _input) = _input.next();
|
||||||
/// Self::run_impl(&a, &b).await
|
/// let (b, _input) = _input.next();
|
||||||
|
/// Self::run_impl(a, b).await
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
@@ -168,36 +169,6 @@ use syn::{parse_macro_input, FnArg, Ident, ImplItem, ItemImpl, Pat, PatType, Ret
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
|
||||||
/// For stateful tasks (with &mut self):
|
|
||||||
///
|
|
||||||
/// ```ignore
|
|
||||||
/// // Your code:
|
|
||||||
/// #[task]
|
|
||||||
/// impl Counter {
|
|
||||||
/// async fn run(&mut self, inc: &i32) -> i32 {
|
|
||||||
/// self.count += inc;
|
|
||||||
/// self.count
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Generated:
|
|
||||||
/// impl Task<(i32)> for Counter {
|
|
||||||
/// type Output = i32;
|
|
||||||
///
|
|
||||||
/// async fn run(&mut self, input: Self::Input) -> Self::Output {
|
|
||||||
/// let inc = input;
|
|
||||||
/// self.run_impl(&inc).await
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl Counter {
|
|
||||||
/// async fn run_impl(&mut self, inc: &i32) -> i32 {
|
|
||||||
/// self.count += inc;
|
|
||||||
/// self.count
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn task(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn task(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
let impl_block = parse_macro_input!(item as ItemImpl);
|
let impl_block = parse_macro_input!(item as ItemImpl);
|
||||||
@@ -273,18 +244,7 @@ pub fn task(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
// Extract return type
|
// Extract return type
|
||||||
let output_type = match &run_method.sig.output {
|
let output_type = match &run_method.sig.output {
|
||||||
ReturnType::Default => syn::parse_quote!(()),
|
ReturnType::Default => syn::parse_quote!(()),
|
||||||
ReturnType::Type(_, ty) => {
|
ReturnType::Type(_, ty) => ty.clone(),
|
||||||
if let Type::Tuple(_tuple) = &**ty {
|
|
||||||
return syn::Error::new_spanned(
|
|
||||||
ty,
|
|
||||||
"Returning bare tuples from task functions is currently not supported.\n\n\
|
|
||||||
Please wrap this in a newtype or struct.",
|
|
||||||
)
|
|
||||||
.into_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
ty.clone()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build Input type based on parameter count
|
// Build Input type based on parameter count
|
||||||
@@ -299,7 +259,7 @@ pub fn task(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
let ident = Ident::new(&format!("__dagx_extract_{}", ident), Span::mixed_site());
|
let ident = Ident::new(&format!("__dagx_extract_{}", ident), Span::mixed_site());
|
||||||
(
|
(
|
||||||
quote! {
|
quote! {
|
||||||
let (#ident, input) = input.next();
|
let (#ident, _input) = _input.next();
|
||||||
},
|
},
|
||||||
ident,
|
ident,
|
||||||
)
|
)
|
||||||
@@ -333,7 +293,7 @@ pub fn task(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
impl ::dagx::Task<#input_type> for #struct_name {
|
impl ::dagx::Task<#input_type> for #struct_name {
|
||||||
type Output = #output_type;
|
type Output = #output_type;
|
||||||
|
|
||||||
async fn run(mut self, mut input: ::dagx::TaskInput<'_, #input_type>) -> Self::Output {
|
async fn run(mut self, mut _input: ::dagx::TaskInput<'_, #input_type>) -> Self::Output {
|
||||||
#param_destructure
|
#param_destructure
|
||||||
#run_call
|
#run_call
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 Stephen Waits <steve@waits.net>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -93,7 +93,7 @@ async fn main() {
|
|||||||
.add_task(Add {
|
.add_task(Add {
|
||||||
label: "Sum".to_string(),
|
label: "Sum".to_string(),
|
||||||
})
|
})
|
||||||
.depends_on((&x, &y)); // Pass handles as a tuple
|
.depends_on((x, y)); // Pass handles as a tuple
|
||||||
// sum is now TaskHandle<i32>
|
// sum is now TaskHandle<i32>
|
||||||
|
|
||||||
// Step 6: Execute the DAG
|
// Step 6: Execute the DAG
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
//! ## Key Concepts
|
//! ## Key Concepts
|
||||||
//! - **Fan-in**: Multiple tasks' outputs are consumed by a single downstream task
|
//! - **Fan-in**: Multiple tasks' outputs are consumed by a single downstream task
|
||||||
//! - **Aggregation**: Combining multiple values into a single result
|
//! - **Aggregation**: Combining multiple values into a single result
|
||||||
//! - **Parameter order**: The order in `.depends_on((&a, &b, &c))` must match
|
//! - **Parameter order**: The order in `.depends_on((a, b, c))` must match
|
||||||
//! the function signature `fn run(a: &T1, b: &T2, c: &T3)`
|
//! the function signature `fn run(a: &T1, b: &T2, c: &T3)`
|
||||||
//!
|
//!
|
||||||
//! ## Use Cases
|
//! ## Use Cases
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
//! This proves dagx runs tasks on multiple CPU cores simultaneously.
|
//! This proves dagx runs tasks on multiple CPU cores simultaneously.
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use dagx::{task, DagResult, DagRunner, Task, TaskInput};
|
use dagx::{task, DagResult, DagRunner};
|
||||||
|
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
@@ -149,15 +149,15 @@ async fn main() -> DagResult<()> {
|
|||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
// Run tasks sequentially (not using DAG, just raw execution)
|
// Run tasks sequentially (not using DAG, just raw execution)
|
||||||
let task1 = ComputeSum::new(1, 251, WORK_DELAY);
|
let mut task1 = ComputeSum::new(1, 251, WORK_DELAY);
|
||||||
let task2 = ComputeSum::new(251, 501, WORK_DELAY);
|
let mut task2 = ComputeSum::new(251, 501, WORK_DELAY);
|
||||||
let task3 = ComputeSum::new(501, 751, WORK_DELAY);
|
let mut task3 = ComputeSum::new(501, 751, WORK_DELAY);
|
||||||
let task4 = ComputeSum::new(751, 1001, WORK_DELAY);
|
let mut task4 = ComputeSum::new(751, 1001, WORK_DELAY);
|
||||||
|
|
||||||
let r1 = task1.run(TaskInput::empty()).await;
|
let r1 = task1.run_impl().await;
|
||||||
let r2 = task2.run(TaskInput::empty()).await;
|
let r2 = task2.run_impl().await;
|
||||||
let r3 = task3.run(TaskInput::empty()).await;
|
let r3 = task3.run_impl().await;
|
||||||
let r4 = task4.run(TaskInput::empty()).await;
|
let r4 = task4.run_impl().await;
|
||||||
|
|
||||||
let result = r1 + r2 + r3 + r4;
|
let result = r1 + r2 + r3 + r4;
|
||||||
let elapsed = start.elapsed();
|
let elapsed = start.elapsed();
|
||||||
|
|||||||
@@ -203,20 +203,18 @@ async fn main() {
|
|||||||
// Stage 3: Statistical analysis (parallel operations on transformed data)
|
// Stage 3: Statistical analysis (parallel operations on transformed data)
|
||||||
let sum = dag
|
let sum = dag
|
||||||
.add_task(ComputeSum)
|
.add_task(ComputeSum)
|
||||||
.depends_on((&transformed_1, &transformed_2, &transformed_3));
|
.depends_on((transformed_1, transformed_2, transformed_3));
|
||||||
|
|
||||||
let product =
|
let product =
|
||||||
dag.add_task(ComputeProduct)
|
dag.add_task(ComputeProduct)
|
||||||
.depends_on((&transformed_1, &transformed_2, &transformed_3));
|
.depends_on((transformed_1, transformed_2, transformed_3));
|
||||||
|
|
||||||
let max = dag
|
let max = dag
|
||||||
.add_task(FindMax)
|
.add_task(FindMax)
|
||||||
.depends_on((&transformed_1, &transformed_2, &transformed_3));
|
.depends_on((transformed_1, transformed_2, transformed_3));
|
||||||
|
|
||||||
// Stage 4: Final report
|
// Stage 4: Final report
|
||||||
let report = dag
|
let report = dag.add_task(GenerateReport).depends_on((sum, product, max));
|
||||||
.add_task(GenerateReport)
|
|
||||||
.depends_on((&sum, &product, &max));
|
|
||||||
|
|
||||||
// Execute the pipeline
|
// Execute the pipeline
|
||||||
println!("Executing pipeline...\n");
|
println!("Executing pipeline...\n");
|
||||||
|
|||||||
+11
-38
@@ -88,7 +88,7 @@ check_pass "Zero clippy warnings"
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "→ Checking for TODO/FIXME/XXX/HACK in source..."
|
echo "→ Checking for TODO/FIXME/XXX/HACK in source..."
|
||||||
TODO_COUNT=$(grep -r "TODO\|FIXME\|XXX\|HACK" src/ dagx-macros/src/ 2>/dev/null | wc -l)
|
TODO_COUNT=$(grep -r "TODO\|FIXME\|XXX\|HACK" src/ dagx-macros/src/ dagx-test/src/ 2>/dev/null | wc -l)
|
||||||
if [ "$TODO_COUNT" -gt 0 ]; then
|
if [ "$TODO_COUNT" -gt 0 ]; then
|
||||||
check_warn "Found $TODO_COUNT TODO/FIXME/HACK comments in source"
|
check_warn "Found $TODO_COUNT TODO/FIXME/HACK comments in source"
|
||||||
else
|
else
|
||||||
@@ -209,6 +209,7 @@ echo ""
|
|||||||
echo "→ Verifying LICENSE..."
|
echo "→ Verifying LICENSE..."
|
||||||
[ -f LICENSE ] || check_fail "LICENSE missing"
|
[ -f LICENSE ] || check_fail "LICENSE missing"
|
||||||
[ -f dagx-macros/LICENSE ] || check_fail "dagx-macros/LICENSE missing"
|
[ -f dagx-macros/LICENSE ] || check_fail "dagx-macros/LICENSE missing"
|
||||||
|
[ -f dagx-test/LICENSE ] || check_fail "dagx-test/LICENSE missing"
|
||||||
check_pass "LICENSE files present in both crates"
|
check_pass "LICENSE files present in both crates"
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -259,45 +260,13 @@ echo "→ Verifying benchmarks compile..."
|
|||||||
cargo bench --no-run || check_fail "Benchmarks failed to compile"
|
cargo bench --no-run || check_fail "Benchmarks failed to compile"
|
||||||
check_pass "Benchmarks compile successfully"
|
check_pass "Benchmarks compile successfully"
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# CARGO.TOML METADATA VERIFICATION
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
section "CARGO.TOML METADATA"
|
|
||||||
|
|
||||||
echo "→ Checking dagx Cargo.toml..."
|
|
||||||
grep -q 'name = "dagx"' Cargo.toml || check_fail "Package name incorrect"
|
|
||||||
grep -q "version = \"$VERSION\"" Cargo.toml || check_fail "Version not $VERSION"
|
|
||||||
grep -q 'edition = "2021"' Cargo.toml || check_fail "Edition not 2021"
|
|
||||||
grep -q 'license = "MIT"' Cargo.toml || check_fail "License not MIT"
|
|
||||||
grep -q 'description = "A minimal, type-safe' Cargo.toml || check_fail "Description missing"
|
|
||||||
grep -q 'repository = "https://github.com/swaits/dagx"' Cargo.toml || check_fail "Repository URL incorrect"
|
|
||||||
grep -q 'homepage = "https://github.com/swaits/dagx"' Cargo.toml || check_fail "Homepage URL incorrect"
|
|
||||||
grep -q 'documentation = "https://docs.rs/dagx"' Cargo.toml || check_fail "Documentation URL incorrect"
|
|
||||||
grep -q 'readme = "README.md"' Cargo.toml || check_fail "README not specified"
|
|
||||||
grep -q 'keywords = \["dag"' Cargo.toml || check_fail "Keywords missing"
|
|
||||||
grep -q 'categories = \["asynchronous"' Cargo.toml || check_fail "Categories missing"
|
|
||||||
check_pass "dagx Cargo.toml metadata complete and correct"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "→ Checking dagx-macros Cargo.toml..."
|
|
||||||
grep -q 'name = "dagx-macros"' dagx-macros/Cargo.toml || check_fail "dagx-macros name incorrect"
|
|
||||||
grep -q "version = \"$VERSION\"" dagx-macros/Cargo.toml || check_fail "dagx-macros version not $VERSION"
|
|
||||||
grep -q 'edition = "2021"' dagx-macros/Cargo.toml || check_fail "dagx-macros edition not 2021"
|
|
||||||
grep -q 'license = "MIT"' dagx-macros/Cargo.toml || check_fail "dagx-macros license not MIT"
|
|
||||||
grep -q 'description = "Procedural macros for dagx"' dagx-macros/Cargo.toml || check_fail "dagx-macros description missing"
|
|
||||||
grep -q 'repository = "https://github.com/swaits/dagx"' dagx-macros/Cargo.toml || check_fail "dagx-macros repository URL incorrect"
|
|
||||||
grep -q 'homepage = "https://github.com/swaits/dagx"' dagx-macros/Cargo.toml || check_fail "dagx-macros homepage URL incorrect"
|
|
||||||
grep -q 'documentation = "https://docs.rs/dagx-macros"' dagx-macros/Cargo.toml || check_fail "dagx-macros documentation URL incorrect"
|
|
||||||
grep -q 'readme = "README.md"' dagx-macros/Cargo.toml || check_fail "dagx-macros README not specified"
|
|
||||||
check_pass "dagx-macros Cargo.toml metadata complete and correct"
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "→ Verifying version consistency..."
|
echo "→ Verifying version consistency..."
|
||||||
DAGX_VERSION=$(grep '^version = ' Cargo.toml | head -1 | cut -d'"' -f2)
|
DAGX_VERSION=$(grep '^version = ' Cargo.toml | head -1 | cut -d'"' -f2)
|
||||||
MACROS_VERSION=$(grep '^version = ' dagx-macros/Cargo.toml | head -1 | cut -d'"' -f2)
|
MACROS_VERSION=$(grep '^version = ' dagx-macros/Cargo.toml | head -1 | cut -d'"' -f2)
|
||||||
if [ "$DAGX_VERSION" != "$MACROS_VERSION" ]; then
|
TEST_VERSION=$(grep '^version = ' dagx-test/Cargo.toml | head -1 | cut -d'"' -f2)
|
||||||
check_fail "Version mismatch: dagx=$DAGX_VERSION, dagx-macros=$MACROS_VERSION"
|
if [ "$DAGX_VERSION" != "$MACROS_VERSION" ] || [ "$DAGX_VERSION" != "$TEST_VERSION" ]; then
|
||||||
|
check_fail "Version mismatch: dagx=$DAGX_VERSION, dagx-macros=$MACROS_VERSION, dagx-test=$TEST_VERSION"
|
||||||
else
|
else
|
||||||
check_pass "Versions match: both are $DAGX_VERSION"
|
check_pass "Versions match: both are $DAGX_VERSION"
|
||||||
fi
|
fi
|
||||||
@@ -344,7 +313,7 @@ fi
|
|||||||
section "SECURITY CHECKS"
|
section "SECURITY CHECKS"
|
||||||
|
|
||||||
echo "→ Checking for sensitive data..."
|
echo "→ Checking for sensitive data..."
|
||||||
if grep -r "api[_-]key\|secret\|password\|token" src/ dagx-macros/src/ 2>/dev/null | grep -v "^Binary" | grep -v "token for a node" | grep -q .; then
|
if grep -r "api[_-]key\|secret\|password\|token" src/ dagx-macros/src/ dagx-test/src 2>/dev/null | grep -v "^Binary" | grep -v "token for a node" | grep -q .; then
|
||||||
check_fail "Potential sensitive data found in source"
|
check_fail "Potential sensitive data found in source"
|
||||||
else
|
else
|
||||||
check_pass "No sensitive data found"
|
check_pass "No sensitive data found"
|
||||||
@@ -387,7 +356,11 @@ echo "4. Then publish dagx:"
|
|||||||
echo " cd .."
|
echo " cd .."
|
||||||
echo " cargo publish"
|
echo " cargo publish"
|
||||||
echo ""
|
echo ""
|
||||||
echo "5. Push changes and bookmark:"
|
echo "5. Then publish dagx-test:"
|
||||||
|
echo " cd dagx-test"
|
||||||
|
echo " cargo publish"
|
||||||
|
echo ""
|
||||||
|
echo "6. Push changes and bookmark:"
|
||||||
echo " jj git push"
|
echo " jj git push"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${BLUE}Note: dagx-macros MUST be published before dagx${NC}"
|
echo -e "${BLUE}Note: dagx-macros MUST be published before dagx${NC}"
|
||||||
|
|||||||
@@ -212,13 +212,6 @@ impl<T> Clone for TaskHandle<T> {
|
|||||||
|
|
||||||
impl<T> Copy for TaskHandle<T> {}
|
impl<T> Copy for TaskHandle<T> {}
|
||||||
|
|
||||||
// TaskHandle can be converted from &TaskHandle (for .get() calls)
|
|
||||||
impl<T> From<&TaskHandle<T>> for TaskHandle<T> {
|
|
||||||
fn from(handle: &TaskHandle<T>) -> Self {
|
|
||||||
*handle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Takes a task and converts it to either a TaskBuilder or a TaskHandle,
|
/// Takes a task and converts it to either a TaskBuilder or a TaskHandle,
|
||||||
/// depending on whether it has inputs or not.
|
/// depending on whether it has inputs or not.
|
||||||
///
|
///
|
||||||
@@ -269,8 +262,6 @@ macro_rules! impl_wire_tuple {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate DepsTuple implementations for tuples of size 2-8.
|
|
||||||
// Supporting up to 8 elements covers the vast majority of use cases.
|
|
||||||
impl_wire_tuple!(T1);
|
impl_wire_tuple!(T1);
|
||||||
impl_wire_tuple!(T1, T2);
|
impl_wire_tuple!(T1, T2);
|
||||||
impl_wire_tuple!(T1, T2, T3);
|
impl_wire_tuple!(T1, T2, T3);
|
||||||
|
|||||||
+9
-21
@@ -21,21 +21,9 @@ impl DepsTuple<()> for () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implementation for single dependency (all forms)
|
// Implementation for single dependency (all forms)
|
||||||
impl<T, O> DepsTuple<(O,)> for T
|
impl<O> DepsTuple<(O,)> for TaskHandle<O> {
|
||||||
where
|
|
||||||
T: Into<TaskHandle<O>>,
|
|
||||||
{
|
|
||||||
fn to_node_ids(self) -> Vec<NodeId> {
|
fn to_node_ids(self) -> Vec<NodeId> {
|
||||||
vec![self.into().id]
|
vec![self.id]
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, O> DepsTuple<O> for (T,)
|
|
||||||
where
|
|
||||||
T: Into<TaskHandle<O>>,
|
|
||||||
{
|
|
||||||
fn to_node_ids(self) -> Vec<NodeId> {
|
|
||||||
vec![self.0.into().id]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,27 +35,27 @@ where
|
|||||||
/// This allows flexible dependency specification:
|
/// This allows flexible dependency specification:
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// // Using handles
|
/// // Using handles
|
||||||
/// task.depends_on((&handle_a, &handle_b))
|
/// task.depends_on((handle_a, handle_b))
|
||||||
///
|
///
|
||||||
/// // Using builders directly
|
/// // Using builders directly
|
||||||
/// task.depends_on((&dag.add_task(TaskA), &dag.add_task(TaskB)))
|
/// task.depends_on((dag.add_task(TaskA), dag.add_task(TaskB)))
|
||||||
/// ```
|
/// ```
|
||||||
macro_rules! impl_deps_tuple {
|
macro_rules! impl_deps_tuple {
|
||||||
($($T:ident : $O:ident),+) => {
|
($($T:ident : $O:ident),+) => {
|
||||||
// For tuples of any combination of &TaskHandle, TaskHandle, and TaskBuilder
|
impl<$($O),+> DepsTuple<($($O,)+)> for ($(TaskHandle<$O>,)+)
|
||||||
impl<$($T: Into<TaskHandle<$O>>, $O),+> DepsTuple<($($O,)+)> for ($($T,)+)
|
|
||||||
{
|
{
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn to_node_ids(self) -> Vec<NodeId> {
|
fn to_node_ids(self) -> Vec<NodeId> {
|
||||||
let ($($T,)+) = self;
|
let ($($O,)+) = self;
|
||||||
vec![$($T.into().id,)+]
|
vec![$($O.id,)+]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate DepsTuple implementations for tuples of size 2-8.
|
// Generate DepsTuple implementations for tuples of size 1-8.
|
||||||
// Supporting up to 8 elements covers the vast majority of use cases.
|
// Supporting up to 8 elements covers the vast majority of use cases.
|
||||||
|
impl_deps_tuple!(T1:O1);
|
||||||
impl_deps_tuple!(T1:O1, T2:O2);
|
impl_deps_tuple!(T1:O1, T2:O2);
|
||||||
impl_deps_tuple!(T1:O1, T2:O2, T3:O3);
|
impl_deps_tuple!(T1:O1, T2:O2, T3:O3);
|
||||||
impl_deps_tuple!(T1:O1, T2:O2, T3:O3, T4:O4);
|
impl_deps_tuple!(T1:O1, T2:O2, T3:O3, T4:O4);
|
||||||
|
|||||||
+6
-28
@@ -57,7 +57,7 @@ fn test_deps_tuple_single_handle_tuple_ref() {
|
|||||||
id: NodeId(7),
|
id: NodeId(7),
|
||||||
_phantom: std::marker::PhantomData,
|
_phantom: std::marker::PhantomData,
|
||||||
};
|
};
|
||||||
let node_ids = (&handle,).to_node_ids();
|
let node_ids = (handle,).to_node_ids();
|
||||||
assert_eq!(node_ids.len(), 1);
|
assert_eq!(node_ids.len(), 1);
|
||||||
assert_eq!(node_ids[0], NodeId(7));
|
assert_eq!(node_ids[0], NodeId(7));
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ fn test_deps_tuple_multiple_handles() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Test 2-tuple
|
// Test 2-tuple
|
||||||
let node_ids = (&handle1, &handle2).to_node_ids();
|
let node_ids = (handle1, handle2).to_node_ids();
|
||||||
assert_eq!(node_ids.len(), 2);
|
assert_eq!(node_ids.len(), 2);
|
||||||
assert_eq!(node_ids[0], NodeId(1));
|
assert_eq!(node_ids[0], NodeId(1));
|
||||||
assert_eq!(node_ids[1], NodeId(2));
|
assert_eq!(node_ids[1], NodeId(2));
|
||||||
@@ -124,7 +124,7 @@ fn test_deps_tuple_multiple_handles() {
|
|||||||
id: NodeId(3),
|
id: NodeId(3),
|
||||||
_phantom: std::marker::PhantomData,
|
_phantom: std::marker::PhantomData,
|
||||||
};
|
};
|
||||||
let node_ids = (&handle1, &handle2, &handle3).to_node_ids();
|
let node_ids = (handle1, handle2, handle3).to_node_ids();
|
||||||
assert_eq!(node_ids.len(), 3);
|
assert_eq!(node_ids.len(), 3);
|
||||||
assert_eq!(node_ids[0], NodeId(1));
|
assert_eq!(node_ids[0], NodeId(1));
|
||||||
assert_eq!(node_ids[1], NodeId(2));
|
assert_eq!(node_ids[1], NodeId(2));
|
||||||
@@ -162,7 +162,7 @@ fn test_deps_tuple_large_tuples() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test 4-tuple
|
// Test 4-tuple
|
||||||
let node_ids = (&handles[0], &handles[1], &handles[2], &handles[3]).to_node_ids();
|
let node_ids = (handles[0], handles[1], handles[2], handles[3]).to_node_ids();
|
||||||
assert_eq!(node_ids.len(), 4);
|
assert_eq!(node_ids.len(), 4);
|
||||||
for (i, node_id) in node_ids.iter().enumerate().take(4) {
|
for (i, node_id) in node_ids.iter().enumerate().take(4) {
|
||||||
assert_eq!(*node_id, NodeId(i as u32));
|
assert_eq!(*node_id, NodeId(i as u32));
|
||||||
@@ -170,14 +170,8 @@ fn test_deps_tuple_large_tuples() {
|
|||||||
|
|
||||||
// Test 8-tuple
|
// Test 8-tuple
|
||||||
let node_ids = (
|
let node_ids = (
|
||||||
&handles[0],
|
handles[0], handles[1], handles[2], handles[3], handles[4], handles[5], handles[6],
|
||||||
&handles[1],
|
handles[7],
|
||||||
&handles[2],
|
|
||||||
&handles[3],
|
|
||||||
&handles[4],
|
|
||||||
&handles[5],
|
|
||||||
&handles[6],
|
|
||||||
&handles[7],
|
|
||||||
)
|
)
|
||||||
.to_node_ids();
|
.to_node_ids();
|
||||||
assert_eq!(node_ids.len(), 8);
|
assert_eq!(node_ids.len(), 8);
|
||||||
@@ -185,19 +179,3 @@ fn test_deps_tuple_large_tuples() {
|
|||||||
assert_eq!(*node_id, NodeId(i as u32));
|
assert_eq!(*node_id, NodeId(i as u32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deps_handle_ref_explicit() {
|
|
||||||
// Test explicit &TaskHandle DepsTuple impl (line 27-28 in deps.rs)
|
|
||||||
let handle: TaskHandle<i32> = TaskHandle {
|
|
||||||
id: NodeId(77),
|
|
||||||
_phantom: std::marker::PhantomData,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a reference and explicitly call to_node_ids
|
|
||||||
let handle_ref = &handle;
|
|
||||||
let node_ids = DepsTuple::<(i32,)>::to_node_ids(handle_ref);
|
|
||||||
|
|
||||||
assert_eq!(node_ids.len(), 1);
|
|
||||||
assert_eq!(node_ids[0], NodeId(77));
|
|
||||||
}
|
|
||||||
+6
-5
@@ -320,8 +320,8 @@
|
|||||||
//! let mut dag = DagRunner::new();
|
//! let mut dag = DagRunner::new();
|
||||||
//!
|
//!
|
||||||
//! let base = dag.add_task(Value(10)).into();
|
//! let base = dag.add_task(Value(10)).into();
|
||||||
//! let plus1 = dag.add_task(Add(1)).depends_on(&base);
|
//! let plus1 = dag.add_task(Add(1)).depends_on(base);
|
||||||
//! let times2 = dag.add_task(Scale(2)).depends_on(&base);
|
//! let times2 = dag.add_task(Scale(2)).depends_on(base);
|
||||||
//!
|
//!
|
||||||
//!let mut output = dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() }).await.unwrap();
|
//!let mut output = dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() }).await.unwrap();
|
||||||
//!
|
//!
|
||||||
@@ -656,9 +656,9 @@
|
|||||||
//! let data = dag.add_task(FetchData).into();
|
//! let data = dag.add_task(FetchData).into();
|
||||||
//!
|
//!
|
||||||
//! // All three tasks get efficient Arc-wrapped sharing automatically
|
//! // All three tasks get efficient Arc-wrapped sharing automatically
|
||||||
//! let task1 = dag.add_task(ProcessData).depends_on(&data);
|
//! let task1 = dag.add_task(ProcessData).depends_on(data);
|
||||||
//! let task2 = dag.add_task(ProcessData).depends_on(&data);
|
//! let task2 = dag.add_task(ProcessData).depends_on(data);
|
||||||
//! let task3 = dag.add_task(ProcessData).depends_on(&data);
|
//! let task3 = dag.add_task(ProcessData).depends_on(data);
|
||||||
//!
|
//!
|
||||||
//!let mut output = dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() }).await.unwrap();
|
//!let mut output = dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() }).await.unwrap();
|
||||||
//! # };
|
//! # };
|
||||||
@@ -784,4 +784,5 @@ pub use runner::DagRunner;
|
|||||||
pub use task::{Task, TaskInput};
|
pub use task::{Task, TaskInput};
|
||||||
|
|
||||||
// Re-export the procedural macro
|
// Re-export the procedural macro
|
||||||
|
#[cfg(feature = "derive")]
|
||||||
pub use dagx_macros::task;
|
pub use dagx_macros::task;
|
||||||
+1
-4
@@ -51,10 +51,7 @@ impl DagOutput {
|
|||||||
/// assert_eq!(output.get(task).unwrap(), 42);
|
/// assert_eq!(output.get(task).unwrap(), 42);
|
||||||
/// # };
|
/// # };
|
||||||
/// ```
|
/// ```
|
||||||
pub fn get<T: 'static + Send + Sync, H>(&mut self, handle: H) -> DagResult<T>
|
pub fn get<T: 'static + Send + Sync>(&mut self, handle: TaskHandle<T>) -> DagResult<T> {
|
||||||
where
|
|
||||||
H: Into<TaskHandle<T>>,
|
|
||||||
{
|
|
||||||
let handle: TaskHandle<T> = handle.into();
|
let handle: TaskHandle<T> = handle.into();
|
||||||
|
|
||||||
let arc_output = self
|
let arc_output = self
|
||||||
|
|||||||
+6
-6
@@ -460,13 +460,13 @@ impl DagRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Return first error if any
|
// Return first error if any
|
||||||
if let Some(err) = first_error {
|
if let Some(err) = first_error {
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
error!(?err, "DAG execution failed");
|
error!(?err, "DAG execution failed");
|
||||||
return Err(err);
|
return Err(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
|
|||||||
@@ -140,14 +140,5 @@ impl_task_input!(A, B, C, D, E, F);
|
|||||||
impl_task_input!(A, B, C, D, E, F, G);
|
impl_task_input!(A, B, C, D, E, F, G);
|
||||||
impl_task_input!(A, B, C, D, E, F, G, H);
|
impl_task_input!(A, B, C, D, E, F, G, H);
|
||||||
|
|
||||||
impl TaskInput<'static, ()> {
|
|
||||||
pub fn empty() -> Self {
|
|
||||||
Self {
|
|
||||||
inputs: [].iter(),
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
@@ -32,9 +32,3 @@ async fn test_custom_task_implementation() {
|
|||||||
// Can't call run again since task was consumed
|
// Can't call run again since task was consumed
|
||||||
// This demonstrates the ownership model
|
// This demonstrates the ownership model
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_empty_task_input() {
|
|
||||||
let empty = TaskInput::empty();
|
|
||||||
assert_eq!(empty.inputs.len(), 0);
|
|
||||||
}
|
|
||||||
@@ -41,14 +41,14 @@ async fn test_multiple_parallel_deep_chains() -> DagResult<()> {
|
|||||||
},
|
},
|
||||||
))
|
))
|
||||||
.depends_on((
|
.depends_on((
|
||||||
&chain_ends[0],
|
chain_ends[0],
|
||||||
&chain_ends[1],
|
chain_ends[1],
|
||||||
&chain_ends[2],
|
chain_ends[2],
|
||||||
&chain_ends[3],
|
chain_ends[3],
|
||||||
&chain_ends[4],
|
chain_ends[4],
|
||||||
&chain_ends[5],
|
chain_ends[5],
|
||||||
&chain_ends[6],
|
chain_ends[6],
|
||||||
&chain_ends[7],
|
chain_ends[7],
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
@@ -120,7 +120,7 @@ async fn test_deep_binary_tree() -> DagResult<()> {
|
|||||||
dag.add_task(task_fn::<(i32, i32), _, _>(move |(l, r): (&i32, &i32)| {
|
dag.add_task(task_fn::<(i32, i32), _, _>(move |(l, r): (&i32, &i32)| {
|
||||||
l + r
|
l + r
|
||||||
}))
|
}))
|
||||||
.depends_on((&left, &right))
|
.depends_on((left, right))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ async fn test_fibonacci_chain() -> DagResult<()> {
|
|||||||
for _ in 2..50 {
|
for _ in 2..50 {
|
||||||
let next = dag
|
let next = dag
|
||||||
.add_task(task_fn::<(i64, i64), _, _>(|(a, b): (&i64, &i64)| a + b))
|
.add_task(task_fn::<(i64, i64), _, _>(|(a, b): (&i64, &i64)| a + b))
|
||||||
.depends_on((&prev2, &prev1));
|
.depends_on((prev2, prev1));
|
||||||
|
|
||||||
prev2 = prev1;
|
prev2 = prev1;
|
||||||
prev1 = next;
|
prev1 = next;
|
||||||
@@ -196,7 +196,7 @@ async fn test_zigzag_dependencies() -> DagResult<()> {
|
|||||||
// Final task depends on both chains
|
// Final task depends on both chains
|
||||||
let final_task = dag
|
let final_task = dag
|
||||||
.add_task(task_fn::<(i32, i32), _, _>(|(a, b): (&i32, &i32)| a + b))
|
.add_task(task_fn::<(i32, i32), _, _>(|(a, b): (&i32, &i32)| a + b))
|
||||||
.depends_on((&chain_a, &chain_b));
|
.depends_on((chain_a, chain_b));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ async fn test_type_safety_prevents_invalid_graphs() {
|
|||||||
let t2 = dag.add_task(Transform).depends_on(s2);
|
let t2 = dag.add_task(Transform).depends_on(s2);
|
||||||
|
|
||||||
// Aggregate depends on transforms
|
// Aggregate depends on transforms
|
||||||
let result = dag.add_task(Aggregate).depends_on((&t1, &t2));
|
let result = dag.add_task(Aggregate).depends_on((t1, t2));
|
||||||
|
|
||||||
// Execute and verify
|
// Execute and verify
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ async fn test_four_dependencies() -> DagResult<()> {
|
|||||||
.add_task(task_fn::<(i32, i32, i32, i32), _, _>(
|
.add_task(task_fn::<(i32, i32, i32, i32), _, _>(
|
||||||
|(a, b, c, d): (&i32, &i32, &i32, &i32)| a + b + c + d,
|
|(a, b, c, d): (&i32, &i32, &i32, &i32)| a + b + c + d,
|
||||||
))
|
))
|
||||||
.depends_on((&deps[0], &deps[1], &deps[2], &deps[3]));
|
.depends_on((deps[0], deps[1], deps[2], deps[3]));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||||
@@ -76,7 +76,7 @@ async fn test_five_dependencies() -> DagResult<()> {
|
|||||||
.add_task(task_fn::<(i32, i32, i32, i32, i32), _, _>(
|
.add_task(task_fn::<(i32, i32, i32, i32, i32), _, _>(
|
||||||
|(a, b, c, d, e): (&i32, &i32, &i32, &i32, &i32)| a + b + c + d + e,
|
|(a, b, c, d, e): (&i32, &i32, &i32, &i32, &i32)| a + b + c + d + e,
|
||||||
))
|
))
|
||||||
.depends_on((&deps[0], &deps[1], &deps[2], &deps[3], &deps[4]));
|
.depends_on((deps[0], deps[1], deps[2], deps[3], deps[4]));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||||
@@ -98,7 +98,7 @@ async fn test_six_dependencies() -> DagResult<()> {
|
|||||||
.add_task(task_fn::<(i32, i32, i32, i32, i32, i32), _, _>(
|
.add_task(task_fn::<(i32, i32, i32, i32, i32, i32), _, _>(
|
||||||
|(a, b, c, d, e, f): (&i32, &i32, &i32, &i32, &i32, &i32)| a + b + c + d + e + f,
|
|(a, b, c, d, e, f): (&i32, &i32, &i32, &i32, &i32, &i32)| a + b + c + d + e + f,
|
||||||
))
|
))
|
||||||
.depends_on((&deps[0], &deps[1], &deps[2], &deps[3], &deps[4], &deps[5]));
|
.depends_on((deps[0], deps[1], deps[2], deps[3], deps[4], deps[5]));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||||
@@ -123,7 +123,7 @@ async fn test_seven_dependencies() -> DagResult<()> {
|
|||||||
},
|
},
|
||||||
))
|
))
|
||||||
.depends_on((
|
.depends_on((
|
||||||
&deps[0], &deps[1], &deps[2], &deps[3], &deps[4], &deps[5], &deps[6],
|
deps[0], deps[1], deps[2], deps[3], deps[4], deps[5], deps[6],
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
@@ -149,7 +149,7 @@ async fn test_eight_dependencies() -> DagResult<()> {
|
|||||||
},
|
},
|
||||||
))
|
))
|
||||||
.depends_on((
|
.depends_on((
|
||||||
&deps[0], &deps[1], &deps[2], &deps[3], &deps[4], &deps[5], &deps[6], &deps[7],
|
deps[0], deps[1], deps[2], deps[3], deps[4], deps[5], deps[6], deps[7],
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ async fn test_diamond_error_propagation() {
|
|||||||
.depends_on(source);
|
.depends_on(source);
|
||||||
|
|
||||||
dag.add_task(task_fn::<(i32, i32), _, _>(|(l, r): (&i32, &i32)| l + r))
|
dag.add_task(task_fn::<(i32, i32), _, _>(|(l, r): (&i32, &i32)| l + r))
|
||||||
.depends_on((&left, &right));
|
.depends_on((left, right));
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
dag.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ async fn test_diamond_dependency() {
|
|||||||
.depends_on(a);
|
.depends_on(a);
|
||||||
let d = dag
|
let d = dag
|
||||||
.add_task(task_fn::<(i32, i32), _, _>(|(x, y): (&i32, &i32)| x + y))
|
.add_task(task_fn::<(i32, i32), _, _>(|(x, y): (&i32, &i32)| x + y))
|
||||||
.depends_on((&b, &c));
|
.depends_on((b, c));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ async fn test_layered_interleaving() -> DagResult<()> {
|
|||||||
dag.add_task(Layer23Task {
|
dag.add_task(Layer23Task {
|
||||||
active: layer_active.clone(),
|
active: layer_active.clone(),
|
||||||
})
|
})
|
||||||
.depends_on((&layer1[idx], &layer1[idx + 1]))
|
.depends_on((layer1[idx], layer1[idx + 1]))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ async fn test_layered_interleaving() -> DagResult<()> {
|
|||||||
.add_task(Layer23Task {
|
.add_task(Layer23Task {
|
||||||
active: layer_active.clone(),
|
active: layer_active.clone(),
|
||||||
})
|
})
|
||||||
.depends_on((&layer2[0], &layer2[1]));
|
.depends_on((layer2[0], layer2[1]));
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
.run(|fut| async move { tokio::spawn(fut).await.unwrap() })
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ async fn test_layers_execute_in_parallel() -> DagResult<()> {
|
|||||||
a + b + c
|
a + b + c
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.depends_on((&layer1[0], &layer1[1], &layer1[2]))
|
.depends_on((layer1[0], layer1[1], layer1[2]))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut output = dag
|
let mut output = dag
|
||||||
|
|||||||
Reference in new issue
Block a user