Files
attune/docs/sensors/timer-sensor-implementation.md
2026-02-04 17:46:30 -06:00

6.6 KiB

Timer Sensor Implementation

Overview

The timer sensor (attune-core-timer-sensor) is a standalone sensor service that monitors all timer-based triggers in Attune and fires events according to their schedules. It uses the tokio-cron-scheduler library for efficient asynchronous scheduling.

Supported Timer Types

The timer sensor supports three distinct timer types, each with its own use case:

1. Interval Timers (core.intervaltimer)

Fires at regular intervals based on a specified time unit and interval value.

Use Cases:

  • Periodic health checks
  • Regular data synchronization
  • Scheduled backups
  • Continuous monitoring tasks

Configuration:

trigger_ref: core.intervaltimer
parameters:
  unit: "seconds"    # Options: seconds, minutes, hours, days
  interval: 30       # Fire every 30 seconds

Event Payload:

{
  "type": "interval",
  "interval_seconds": 30,
  "fired_at": "2024-01-20T15:30:00Z",
  "execution_count": 42,
  "sensor_ref": "core.interval_timer_sensor"
}

Examples:

  • Fire every 10 seconds: {unit: "seconds", interval: 10}
  • Fire every 5 minutes: {unit: "minutes", interval: 5}
  • Fire every 2 hours: {unit: "hours", interval: 2}
  • Fire daily: {unit: "days", interval: 1}

2. Cron Timers (core.crontimer)

Fires based on cron schedule expressions, providing flexible scheduling with fine-grained control.

Use Cases:

  • Business hour operations (weekdays 9-5)
  • Scheduled reports (daily at midnight, weekly on Monday)
  • Complex recurring schedules
  • Time-zone-aware scheduling

Configuration:

trigger_ref: core.crontimer
parameters:
  expression: "0 0 9 * * 1-5"  # Weekdays at 9 AM
  timezone: "UTC"               # Optional, defaults to UTC

Cron Format:

second minute hour day_of_month month day_of_week
  |      |     |        |         |        |
  0-59  0-59  0-23    1-31      1-12    0-6 (0=Sun)

Event Payload:

{
  "type": "cron",
  "fired_at": "2024-01-20T09:00:00Z",
  "scheduled_at": "2024-01-20T09:00:00Z",
  "expression": "0 0 9 * * 1-5",
  "timezone": "UTC",
  "next_fire_at": "2024-01-21T09:00:00Z",
  "execution_count": 15,
  "sensor_ref": "core.interval_timer_sensor"
}

Examples:

  • Every hour: "0 0 * * * *"
  • Every 15 minutes: "0 */15 * * * *"
  • Daily at midnight: "0 0 0 * * *"
  • Weekdays at 9 AM: "0 0 9 * * 1-5"
  • Every Monday at 8:30 AM: "0 30 8 * * 1"

3. DateTime Timers (core.datetimetimer)

Fires once at a specific date and time. This is a one-shot timer that automatically removes itself after firing.

Use Cases:

  • Scheduled deployments
  • One-time notifications
  • Event reminders
  • Deadline triggers

Configuration:

trigger_ref: core.datetimetimer
parameters:
  fire_at: "2024-12-31T23:59:59Z"  # ISO 8601 timestamp
  timezone: "UTC"                   # Optional, defaults to UTC

Event Payload:

{
  "type": "one_shot",
  "fire_at": "2024-12-31T23:59:59Z",
  "fired_at": "2024-12-31T23:59:59.123Z",
  "timezone": "UTC",
  "delay_ms": 123,
  "sensor_ref": "core.interval_timer_sensor"
}

Examples:

  • New Year countdown: {fire_at: "2024-12-31T23:59:59Z"}
  • Specific deployment time: {fire_at: "2024-06-15T14:00:00Z", timezone: "America/New_York"}

Implementation Details

Architecture

The timer sensor uses a shared JobScheduler from tokio-cron-scheduler to manage all timer types efficiently:

  1. Initialization: Creates a JobScheduler instance and starts it
  2. Job Creation: Converts each timer config into the appropriate Job type
  3. Job Management: Tracks active jobs by rule_id → job_uuid mapping
  4. Cleanup: Properly shuts down the scheduler on service termination

Key Components

TimerManager (timer_manager.rs):

  • Central component that manages all timer jobs
  • Methods:
    • new(): Creates and starts the scheduler
    • start_timer(): Adds/replaces a timer for a rule
    • stop_timer(): Removes a specific timer
    • stop_all(): Removes all timers
    • shutdown(): Gracefully shuts down the scheduler

Job Types:

  • Interval: Uses Job::new_repeated_async() with fixed duration
  • Cron: Uses Job::new_async() with cron expression
  • DateTime: Uses Job::new_one_shot_async() with duration until fire time

Event Creation

All timer types create events via the Attune API using the appropriate trigger ref:

  • Interval → core.intervaltimer
  • Cron → core.crontimer
  • DateTime → core.datetimetimer

Each event includes:

  • Trigger-specific metadata (execution count, next fire time, etc.)
  • Timestamp information
  • Sensor reference for tracking

Rule Lifecycle Integration

The timer sensor listens to rule lifecycle events via RabbitMQ:

  • RuleCreated/RuleEnabled: Starts timer for the rule
  • RuleDisabled: Stops timer for the rule
  • RuleDeleted: Stops and removes timer for the rule

Timer configuration is extracted from rule trigger parameters and converted to the appropriate TimerConfig enum variant.

Dependencies

tokio-cron-scheduler = "0.15"  # Core scheduling library
chrono = "0.4"                  # Date/time handling
tokio = { version = "1.41", features = ["full"] }

Testing

The implementation includes comprehensive tests covering:

  1. Unit Tests:

    • Timer creation for all types
    • Validation (zero intervals, past dates, invalid cron)
    • Timer start/stop/restart
    • Job replacement
  2. Integration Tests:

    • Multiple concurrent timers
    • Mixed timer type scenarios
    • Cron expression validation
    • Future datetime validation

Run tests:

cargo test -p core-timer-sensor

Configuration

The timer sensor is configured via environment variables:

ATTUNE_API_URL=http://localhost:8080
ATTUNE_API_TOKEN=<service_account_token>
ATTUNE_SENSOR_REF=core.interval_timer_sensor
ATTUNE_MQ_URL=amqp://guest:guest@localhost:5672
ATTUNE_MQ_EXCHANGE=attune
ATTUNE_LOG_LEVEL=info

Or via stdin JSON for containerized environments.

Future Enhancements

Possible improvements for the timer sensor:

  1. Timezone Support: Full timezone handling for cron expressions (currently UTC only)
  2. Persistence: Store scheduled jobs in database for recovery after restart
  3. Job History: Track execution history and statistics
  4. Advanced Scheduling: Support for job chaining, dependencies, and priorities
  5. Performance Metrics: Expose metrics on job execution timing and success rates

References