Timer Node Implementation

This document describes the implementation details of timer nodes in the Floxide framework.

Overview

Timer nodes in Floxide provide scheduling capabilities with support for various schedule types and proper error handling.

Core Components

TimerNode Trait

The TimerNode trait defines the core interface for scheduled execution:

#[async_trait]
pub trait TimerNode<Context, Action>: Send + Sync
where
    Context: Send + Sync + 'static,
    Action: ActionType + Send + Sync + 'static + Default + Debug,
{
    fn schedule(&self) -> Schedule;
    async fn execute_on_schedule(&self, ctx: &mut Context) -> Result<Action, FloxideError>;
    fn id(&self) -> NodeId;
}

Schedule Types

The Schedule enum supports different scheduling patterns:

pub enum Schedule {
    Once(DateTime<Utc>),
    Periodic(ChronoDuration),
    Cron(String),
}

Implementation Details

Schedule Management

  1. Schedule Types
  2. One-time execution
  3. Periodic execution
  4. Cron-based scheduling

  5. Time Handling

  6. UTC time management
  7. Timezone considerations
  8. Leap second handling

  9. Execution Control

  10. Start/stop capabilities
  11. Pause/resume support
  12. Graceful shutdown

Error Handling

  1. Execution Errors
  2. Proper error propagation
  3. Retry mechanisms
  4. Error reporting

  5. Schedule Errors

  6. Invalid schedule detection
  7. Schedule parsing errors
  8. Recovery strategies

Resource Management

  1. Timer Resources
  2. Efficient timer allocation
  3. Resource cleanup
  4. Memory management

  5. Thread Safety

  6. Thread-safe execution
  7. Safe schedule updates
  8. Proper synchronization

Usage Patterns

Basic Usage

let node = SimpleTimer::new(
    Schedule::Periodic(ChronoDuration::minutes(5)),
    |ctx| { /* execution implementation */ },
);

With Cron Schedule

let node = SimpleTimer::new(
    Schedule::Cron("0 2 * * *".to_string()), // Run at 2 AM daily
    |ctx| {
        match perform_daily_task(ctx) {
            Ok(_) => Ok(DefaultAction::Next),
            Err(e) => Err(e.into()),
        }
    },
);

With Error Handling

let node = SimpleTimer::new(
    Schedule::Once(Utc::now() + ChronoDuration::hours(1)),
    |ctx| {
        if let Err(e) = check_preconditions() {
            return Err(e.into());
        }
        Ok(DefaultAction::complete())
    },
);

Testing

The implementation includes comprehensive tests:

  1. Unit Tests
  2. Schedule parsing
  3. Execution timing
  4. Error handling
  5. Resource cleanup

  6. Integration Tests

  7. Complex schedules
  8. Long-running scenarios
  9. Edge cases

Performance Considerations

  1. Timer Efficiency
  2. Minimal allocations
  3. Efficient scheduling
  4. Low overhead

  5. Resource Usage

  6. Optimized timer pools
  7. Efficient thread usage
  8. Minimal locking

Future Improvements

  1. Enhanced Features
  2. More schedule types
  3. Advanced retry strategies
  4. Schedule composition

  5. Performance Optimizations

  6. Improved timer allocation
  7. Better resource sharing
  8. Enhanced concurrency