7.2 KiB
Timer Sensor Complete Implementation
Date: 2026-02-04
Component: Timer Sensor (attune-core-timer-sensor)
Status: ✅ Complete
Summary
Implemented full support for all three timer trigger types in the timer sensor using tokio-cron-scheduler for efficient asynchronous scheduling. The timer sensor now handles interval timers, cron timers, and one-shot datetime timers seamlessly.
Changes Made
1. Dependencies
- Added:
tokio-cron-scheduler = "0.15"tocrates/sensor-timer/Cargo.toml - Provides robust, async-first cron scheduling with support for:
- Repeated jobs (intervals)
- Cron expression-based scheduling
- One-shot jobs (datetime)
2. Timer Manager Refactoring (timer_manager.rs)
Architecture Changes:
- Replaced individual
JoinHandle<()>per timer with sharedJobSchedulerinstance - Added job UUID tracking:
HashMap<rule_id, job_uuid> - Wrapped scheduler in
Mutexfor safe shutdown access - Made constructor async to initialize and start scheduler
Key Methods Updated:
new()→ async, creates and starts JobSchedulerstart_timer()→ Uses scheduler to add jobs, tracks UUIDsstop_timer()→ Removes jobs from scheduler by UUIDstop_all()→ Removes all tracked jobsshutdown()→ NEW: Gracefully shuts down the scheduler
Job Creation Methods:
// Interval timers
async fn create_interval_job(...) -> Result<Job>
- Uses Job::new_repeated_async()
- Converts time units to seconds
- Creates "core.intervaltimer" events
// Cron timers
async fn create_cron_job(...) -> Result<Job>
- Uses Job::new_async() with cron expression
- Queries next fire time from scheduler
- Creates "core.crontimer" events
// DateTime timers
async fn create_datetime_job(...) -> Result<Job>
- Uses Job::new_one_shot_async()
- Calculates duration until fire time
- Validates fire time is in future
- Creates "core.datetimetimer" events
Event Payloads: Each timer type now generates events with correct trigger ref and payload schema:
| Timer Type | Trigger Ref | Key Fields |
|---|---|---|
| Interval | core.intervaltimer |
interval_seconds, execution_count |
| Cron | core.crontimer |
expression, next_fire_at, execution_count |
| DateTime | core.datetimetimer |
fire_at, fired_at, delay_ms |
3. Main Service (main.rs)
Updated to handle async timer manager:
// Create timer manager (now async)
let timer_manager = TimerManager::new(api_client.clone())
.await
.context("Failed to initialize timer manager")?;
// Shutdown handling
timer_manager.shutdown().await?;
4. Sensor Configuration (packs/core/sensors/interval_timer_sensor.yaml)
Updated to reflect support for all three timer types:
- Changed description from "interval timer" to "timer" sensor
- Added trigger types:
core.crontimer,core.datetimetimer - Updated documentation with examples for all three types
- Clarified that tokio-cron-scheduler is used
5. Comprehensive Testing
Added 4 new integration tests:
test_all_timer_types_comprehensive- Tests all three types concurrentlytest_cron_various_expressions- Validates multiple cron patternstest_datetime_timer_future_validation- Tests various future timestest_mixed_timer_replacement- Tests switching timer types for same rule
Test Results: ✅ 34 tests passing (30 existing + 4 new)
6. Documentation
Created comprehensive documentation:
docs/sensors/timer-sensor-implementation.md (6.7K):
- Overview of all three timer types
- Use cases for each type
- Configuration examples
- Event payload schemas
- Implementation details
- Architecture explanation
- Testing guide
docs/QUICKREF-timer-types.md (2.6K):
- Quick reference for all timer types
- Common examples
- Cron format guide
- Decision matrix for choosing timer type
- Event payload summaries
Technical Highlights
Efficient Scheduling
- Single shared
JobSchedulerfor all timers across all rules - Async-first design with tokio integration
- Low overhead job management with UUID tracking
- Clean job lifecycle: creation → tracking → removal → cleanup
Cron Expression Support
Uses croner crate (via tokio-cron-scheduler) for cron parsing:
- Standard 6-field format:
second minute hour day month weekday - Supports special characters:
*,,,-,/ - Built-in validation of expressions
- Query next execution time
One-Shot Timer Handling
DateTime timers:
- Validate fire time is in future (reject past times)
- Calculate duration until fire time using chrono
- Fire exactly once, then automatically cleaned up
- Track delay between scheduled and actual fire time
Graceful Shutdown
- Stops all active timers
- Properly shuts down scheduler
- Prevents job execution after shutdown signal
- Clean resource cleanup
Example Usage
Interval Timer (Every 30 seconds)
trigger_ref: core.intervaltimer
parameters:
unit: seconds
interval: 30
Cron Timer (Weekdays at 9 AM)
trigger_ref: core.crontimer
parameters:
expression: "0 0 9 * * 1-5"
timezone: "UTC"
DateTime Timer (New Year's Eve)
trigger_ref: core.datetimetimer
parameters:
fire_at: "2024-12-31T23:59:59Z"
timezone: "UTC"
Testing Evidence
$ cargo test -p attune-core-timer-sensor
running 34 tests
test result: ok. 34 passed; 0 failed; 0 ignored
$ cargo check -p attune-core-timer-sensor --all-targets
Finished `dev` profile [unoptimized + debuginfo]
# Zero warnings ✅
Benefits
- Complete Feature Parity: All three timer types now fully functional
- Robust Scheduling: Production-ready cron scheduler library
- Efficient Resource Usage: Single scheduler for all timers
- Clean Architecture: Clear separation of timer types
- Comprehensive Testing: All timer types and edge cases covered
- Well Documented: Implementation guide and quick reference
Future Enhancements
Potential improvements identified in documentation:
- Full timezone support for cron expressions (currently UTC only)
- Persistence for job recovery after restart
- Job execution history and statistics
- Advanced scheduling (chaining, dependencies, priorities)
- Performance metrics and monitoring
Files Modified
crates/sensor-timer/Cargo.toml- Added tokio-cron-scheduler dependencycrates/sensor-timer/src/timer_manager.rs- Complete refactor for all timer typescrates/sensor-timer/src/main.rs- Updated for async constructor and shutdownpacks/core/sensors/interval_timer_sensor.yaml- Updated sensor metadata
Files Created
docs/sensors/timer-sensor-implementation.md- Complete implementation guidedocs/QUICKREF-timer-types.md- Quick reference for timer typeswork-summary/2026-02-04-timer-sensor-complete-implementation.md- This file
Compatibility
- ✅ Backward compatible with existing interval timers
- ✅ Adds new functionality (cron and datetime)
- ✅ No breaking changes to API or configuration
- ✅ Existing rules continue to work unchanged
Conclusion
The timer sensor is now feature-complete with support for all three timer types. The implementation uses industry-standard scheduling patterns, comprehensive testing, and clear documentation. The sensor is production-ready for handling diverse timing requirements in Attune workflows.