Files
attune/docs/guides/quickstart-timer-demo.md
2026-02-04 17:46:30 -06:00

8.2 KiB

Quick Start: Timer Echo Demo

This guide will help you run a simple demonstration of Attune's timer-based automation: an "echo Hello World" action that runs every 10 seconds.

Prerequisites

  • PostgreSQL 14+ running
  • RabbitMQ 3.12+ running
  • Rust toolchain installed
  • jq installed (for setup script)

Architecture Overview

This demo exercises the complete Attune event flow:

Timer Manager → Event → Rule Match → Enforcement → Execution → Worker → Action

Components involved:

  1. Sensor Service - Timer manager fires every 10 seconds
  2. API Service - Provides REST endpoints for rule management
  3. Executor Service - Processes enforcements and schedules executions
  4. Worker Service - Executes the echo action

Step 1: Database Setup

First, ensure your database is running and create the schema:

# Set database URL
export DATABASE_URL="postgresql://user:password@localhost:5432/attune"

# Run migrations
cd attune
sqlx database create
sqlx migrate run

Step 2: Seed Core Pack Data

Load the core pack with timer triggers and basic actions:

psql $DATABASE_URL -f scripts/seed_core_pack.sql

This creates:

  • Core pack with timer triggers and basic actions
  • Timer triggers: core.timer_10s, core.timer_1m, core.timer_hourly
  • Actions: core.echo, core.sleep, core.noop
  • Shell runtime for executing shell commands

Step 3: Configure Services

Create a configuration file or use environment variables:

# config.development.yaml
environment: development

database:
  url: "postgresql://user:password@localhost:5432/attune"
  max_connections: 10

message_queue:
  url: "amqp://guest:guest@localhost:5672/%2F"

api:
  host: "0.0.0.0"
  port: 8080

jwt:
  secret: "your-secret-key-change-in-production"
  access_token_ttl: 3600
  refresh_token_ttl: 604800

worker:
  name: "worker-1"
  max_concurrent_tasks: 10
  task_timeout: 300

Or use environment variables:

export ATTUNE__DATABASE__URL="postgresql://user:password@localhost:5432/attune"
export ATTUNE__MESSAGE_QUEUE__URL="amqp://guest:guest@localhost:5672/%2F"
export ATTUNE__JWT__SECRET="your-secret-key"

Step 4: Create Default User

Create an admin user for API access:

INSERT INTO attune.identity (username, email, password_hash, enabled)
VALUES (
    'admin',
    'admin@example.com',
    -- Password: 'admin' (hashed with Argon2id)
    '$argon2id$v=19$m=19456,t=2,p=1$...',
    true
);

Or use the API's registration endpoint after starting the API service.

Step 5: Start Services

Open 4 terminal windows and start each service:

Terminal 1: API Service

cd attune
cargo run --bin attune-api

Wait for: Attune API Server listening on 0.0.0.0:8080

Terminal 2: Sensor Service

cd attune
cargo run --bin attune-sensor

Wait for: Started X timer triggers

Terminal 3: Executor Service

cd attune
cargo run --bin attune-executor

Wait for: Executor Service initialized successfully

Terminal 4: Worker Service

cd attune
cargo run --bin attune-worker

Wait for: Attune Worker Service is ready

Step 6: Create the Timer Echo Rule

Run the setup script to create a rule that runs echo every 10 seconds:

cd attune
./scripts/setup_timer_echo_rule.sh

The script will:

  1. Authenticate with the API
  2. Verify core pack, trigger, and action exist
  3. Create a rule: core.timer_echo_10s

Step 7: Observe the System

Watch Worker Logs

In the worker terminal, you should see output every 10 seconds:

[INFO] Received execution request: ...
[INFO] Executing action core.echo
[INFO] Action completed successfully

Watch Sensor Logs

In the sensor terminal, you should see:

[DEBUG] Interval timer core.timer_10s fired
[INFO] Generated event 123 from timer trigger core.timer_10s

Watch Executor Logs

In the executor terminal, you should see:

[INFO] Processing enforcement 456
[INFO] Scheduling execution for action core.echo
[INFO] Execution scheduled: 789

Query via API

Check recent executions:

# Get auth token
TOKEN=$(curl -s -X POST http://localhost:8080/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin"}' | jq -r '.data.access_token')

# List recent executions
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8080/api/v1/executions | jq '.data[0:5]'

# Get specific execution details
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8080/api/v1/executions/123 | jq

Step 8: Experiment

Change the Timer Interval

Edit the trigger in the database to fire every 5 seconds:

UPDATE attune.trigger
SET param_schema = '{"type": "interval", "seconds": 5}'
WHERE ref = 'core.timer_10s';

Restart the sensor service to pick up the change.

Change the Echo Message

Update the rule's action parameters:

curl -X PUT http://localhost:8080/api/v1/rules/core.timer_echo_10s \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action_params": {
      "message": "Custom message from timer!"
    }
  }'

Add Rule Conditions

Modify the rule to only fire during business hours (requires implementing rule conditions):

{
  "conditions": {
    "condition": "all",
    "rules": [
      {
        "field": "fired_at",
        "operator": "greater_than",
        "value": "09:00:00"
      },
      {
        "field": "fired_at",
        "operator": "less_than",
        "value": "17:00:00"
      }
    ]
  }
}

Create a Cron-Based Rule

Create a rule that fires on a cron schedule:

curl -X POST http://localhost:8080/api/v1/rules \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "ref": "core.hourly_echo",
    "pack": 1,
    "pack_ref": "core",
    "label": "Hourly Echo",
    "description": "Echoes a message every hour",
    "enabled": true,
    "trigger_ref": "core.timer_hourly",
    "action_ref": "core.echo",
    "action_params": {
      "message": "Hourly chime!"
    }
  }'

Troubleshooting

Timer Not Firing

  1. Check sensor service logs for "Started X timer triggers"
  2. Verify trigger is enabled: SELECT * FROM attune.trigger WHERE ref = 'core.timer_10s';
  3. Check timer configuration: Ensure param_schema has valid timer config

No Executions Created

  1. Check if rule exists and is enabled: SELECT * FROM attune.rule WHERE ref = 'core.timer_echo_10s';
  2. Check sensor logs for event generation
  3. Check executor logs for enforcement processing

Worker Not Executing

  1. Check worker service is running and connected to message queue
  2. Check executor logs for "Execution scheduled" messages
  3. Verify runtime exists: SELECT * FROM attune.runtime WHERE ref = 'shell';
  4. Check worker has permission to execute shell commands

Database Connection Errors

  1. Verify PostgreSQL is running
  2. Check connection string is correct
  3. Ensure attune database exists
  4. Verify migrations ran successfully

Message Queue Errors

  1. Verify RabbitMQ is running
  2. Check connection string is correct
  3. Ensure exchanges and queues are created

Next Steps

  • Add more actions: Create Python or Node.js actions
  • Create workflows: Chain multiple actions together
  • Add policies: Implement concurrency limits or rate limiting
  • Human-in-the-loop: Add inquiry actions that wait for user input
  • Custom sensors: Write sensors that monitor external systems
  • Webhooks: Implement webhook triggers for external events

Clean Up

To stop the demo:

  1. Press Ctrl+C in each service terminal
  2. Disable the rule:
    curl -X PUT http://localhost:8080/api/v1/rules/core.timer_echo_10s \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"enabled": false}'
    
  3. (Optional) Clean up data:
    DELETE FROM attune.execution WHERE created < NOW() - INTERVAL '1 hour';
    DELETE FROM attune.event WHERE created < NOW() - INTERVAL '1 hour';
    DELETE FROM attune.enforcement WHERE created < NOW() - INTERVAL '1 hour';
    

Learn More