Long-Running Node Implementation¶
This document describes the implementation details of long-running nodes in the Floxide framework.
Overview¶
Long-running nodes in Floxide provide support for tasks that may take significant time to complete, with proper progress tracking and cancellation support.
Core Components¶
LongRunningNode Trait¶
The LongRunningNode
trait defines the core interface for long-running tasks:
#[async_trait]
pub trait LongRunningNode<Context, Action>: Send + Sync
where
Context: Send + Sync + 'static,
Action: ActionType + Send + Sync + 'static + Debug,
{
async fn start(&self, ctx: &mut Context) -> Result<(), FloxideError>;
async fn check_progress(&self, ctx: &mut Context) -> Result<Progress, FloxideError>;
async fn cancel(&self, ctx: &mut Context) -> Result<(), FloxideError>;
fn id(&self) -> NodeId;
}
Progress Tracking¶
The Progress
enum represents the current state of a long-running task:
pub enum Progress {
Running(f32), // 0.0 to 1.0
Complete(Action),
Failed(FloxideError),
}
Implementation Details¶
Task Management¶
- Execution Control
- Task initialization
- Progress monitoring
-
Graceful cancellation
-
State Management
- Progress tracking
- State persistence
-
Recovery mechanisms
-
Resource Control
- Resource allocation
- Cleanup procedures
- Memory management
Error Handling¶
- Execution Errors
- Error propagation
- Recovery strategies
-
Error reporting
-
Cancellation Handling
- Safe cancellation
- Resource cleanup
- State consistency
Resource Management¶
- Memory Usage
- Efficient state tracking
- Resource cleanup
-
Memory leak prevention
-
Thread Safety
- Thread-safe execution
- Safe progress updates
- Proper synchronization
Usage Patterns¶
Basic Usage¶
let node = LongRunningTask::new(
|ctx| { /* start implementation */ },
|ctx| { /* progress check implementation */ },
|ctx| { /* cancellation implementation */ },
);
With Progress Tracking¶
let node = LongRunningTask::new(
|ctx| async {
for i in 0..100 {
process_chunk(i)?;
update_progress(i as f32 / 100.0);
}
Ok(())
},
|ctx| async {
let progress = get_current_progress();
if progress >= 1.0 {
Ok(Progress::Complete(DefaultAction::Next))
} else {
Ok(Progress::Running(progress))
}
},
|ctx| async { /* cancellation implementation */ },
);
With Error Handling¶
let node = LongRunningTask::new(
|ctx| async {
if let Err(e) = check_preconditions() {
return Err(e.into());
}
start_processing()
},
|ctx| async {
match check_task_progress() {
Ok(progress) => Ok(Progress::Running(progress)),
Err(e) => Ok(Progress::Failed(e.into())),
}
},
|ctx| async {
cleanup_resources()?;
Ok(())
},
);
Testing¶
The implementation includes comprehensive tests:
- Unit Tests
- Task execution
- Progress tracking
- Cancellation handling
-
Resource cleanup
-
Integration Tests
- Complex workflows
- Error scenarios
- Performance tests
Performance Considerations¶
- Execution Efficiency
- Minimal overhead
- Efficient progress tracking
-
Resource optimization
-
Memory Usage
- Optimized state storage
- Efficient progress updates
- Minimal allocations
Future Improvements¶
- Enhanced Features
- More progress metrics
- Advanced cancellation strategies
-
Extended recovery options
-
Performance Optimizations
- Improved state tracking
- Better resource utilization
- Enhanced concurrency