fix: change where TaskHandle is borrowed to prevent repeat output fetches

This commit is contained in:
TechnoPorg committed 2026-02-20 19:00:18 +01:00
1 parent c8efb00175
commit 9fbe4c2fd8
47 files changed
+323 -513

No files matched your search

+13 -42
View File
@@ -30,40 +30,11 @@ fn test_builder_consumed_by_depends_on() {
let consumer_builder = dag.add_task(Consumer);
// This consumes consumer_builder and returns a TaskHandle
let _consumer_handle = consumer_builder.depends_on(source);
let _consumer_handle = consumer_builder.depends_on(&source);
// We CANNOT use consumer_builder again because it was moved
// This would fail to compile:
// let _consumer2 = consumer_builder.depends_on(source); // ERROR: use of moved value
}
/// Demonstrates that you can only get a TaskHandle by finalizing a builder,
/// and handles are immutable references with no methods to add dependencies
#[test]
fn test_handle_is_immutable_reference() {
struct NoInput;
#[task]
impl NoInput {
async fn run(&self) -> i32 {
100
}
}
let mut dag = DagRunner::new();
let builder = dag.add_task(NoInput);
// Convert to handle (only works because Input = ())
let handle = builder;
// TaskHandle is Copy/Clone - just an ID wrapper
let _copy1 = handle;
let _copy2 = handle;
let _copy3 = handle;
// But TaskHandle has NO methods to modify the DAG
// There's no way to add dependencies to it
// This would fail to compile:
// handle.depends_on(something); // ERROR: no method named `depends_on`
// let _consumer2 = consumer_builder.depends_on(&source); // ERROR: use of moved value
}
/// Documents the ordering constraint that prevents cycles
@@ -108,8 +79,8 @@ fn test_ordering_prevents_cycles() {
// Let's create a valid DAG instead: A→B (B depends on A)
let a_handle = a_builder; // A has no deps (unit input)
let _b_handle = b_builder.depends_on(a_handle);
// Now we could try: a_handle.depends_on(b_handle)?
let _b_handle = b_builder.depends_on(&a_handle);
// Now we could try: a_handle.depends_on(&b_handle)?
// But TaskHandle has no such method!
}
@@ -182,9 +153,9 @@ fn test_three_way_cycle_impossible() {
let _c_builder = dag.add_task(C);
// To create A→C→B→A:
// 1. a_builder.depends_on(c_handle) // Need c_handle
// 2. c_builder.depends_on(b_handle) // Need b_handle
// 3. b_builder.depends_on(a_handle) // Need a_handle (from step 1!)
// 1. a_builder.depends_on(&c_handle) // Need c_handle
// 2. c_builder.depends_on(&b_handle) // Need b_handle
// 3. b_builder.depends_on(&a_handle) // Need a_handle (from step 1!)
//
// But step 3 needs a_handle which doesn't exist until step 1 completes.
// And step 1 needs c_handle which doesn't exist until step 2 completes.
@@ -209,7 +180,7 @@ fn test_self_loop_prevented() {
let _builder = dag.add_task(SelfReferential);
// To create A→A (self-loop):
// builder.depends_on(builder)
// builder.depends_on(&builder)
//
// But this would fail because:
// 1. depends_on() takes `self` by value (moves builder)
@@ -217,7 +188,7 @@ fn test_self_loop_prevented() {
// 3. We can't also use &builder as an argument because it's being moved
//
// This would fail to compile:
// let _handle = builder.depends_on(builder); // ERROR: use of moved value
// let _handle = builder.depends_on(&builder); // ERROR: use of moved value
}
/// Comprehensive test showing all the guardrails
@@ -263,11 +234,11 @@ async fn test_type_safety_prevents_invalid_graphs() {
let s2 = dag.add_task(Source);
// Transform depends on sources
let t1 = dag.add_task(Transform).depends_on(s1);
let t2 = dag.add_task(Transform).depends_on(s2);
let t1 = dag.add_task(Transform).depends_on(&s1);
let t2 = dag.add_task(Transform).depends_on(&s2);
// 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
let mut output = dag
@@ -275,7 +246,7 @@ async fn test_type_safety_prevents_invalid_graphs() {
.await
.unwrap();
assert_eq!(output.get(result).unwrap(), 40); // (10*2) + (10*2)
assert_eq!(output.get(result), 40); // (10*2) + (10*2)
// Now if we wanted to add a cycle, we'd need to:
// - Make one of the Source tasks depend on the Aggregate result