Event System
Overview
Tasker features a comprehensive event-driven architecture that provides deep insights into task execution, workflow orchestration, and system behavior. The event system supports both system events (built-in workflow events) and custom events (business logic events), designed to be production-ready for observability and developer-friendly for building custom integrations.
Architecture
The Tasker event system consists of several key components working together:
Core Components
Events::Publisher - Centralized event publishing using dry-events
EventPublisher Concern - Clean interface for business logic (
publish_step_completed,publish_custom_event)EventPayloadBuilder - Standardized payload creation for consistent data structures
Event Catalog - Complete event discovery and documentation system (system + custom events)
BaseSubscriber - Foundation for creating custom event subscribers
TelemetrySubscriber - Production OpenTelemetry integration
CustomRegistry - Registration and management of custom business events
Event Flow Architecture
System Events
System events are built-in events that track the core workflow execution lifecycle. These events are automatically published by Tasker as tasks and steps execute.
Task Events (Tasker::Constants::TaskEvents)
Tasker::Constants::TaskEvents)Task lifecycle events track the overall progress of workflow execution:
INITIALIZE_REQUESTED
Task creation and setup
task_id, task_name, context
START_REQUESTED
Task processing begins
task_id, started_at
COMPLETED
Task finished successfully
task_id, execution_duration, step_count
FAILED
Task encountered fatal error
task_id, error_message, failed_step_id
RETRY_REQUESTED
Task being retried
task_id, retry_count, reason
CANCELLED
Task manually cancelled
task_id, cancelled_by, reason
Step Events (Tasker::Constants::StepEvents)
Tasker::Constants::StepEvents)Step-level events provide detailed execution tracking:
EXECUTION_REQUESTED
Step queued for processing
task_id, step_id, step_name
BEFORE_HANDLE
Step about to execute
task_id, step_id, attempt_number
HANDLE
Step currently executing
task_id, step_id, started_at
COMPLETED
Step finished successfully
task_id, step_id, execution_duration, results
FAILED
Step encountered error
task_id, step_id, error_message, exception_class, backtrace
RETRY_REQUESTED
Step being retried
task_id, step_id, attempt_number, retry_delay
MAX_RETRIES_REACHED
Step exceeded retry limit
task_id, step_id, final_error
Workflow Events (Tasker::Constants::WorkflowEvents)
Tasker::Constants::WorkflowEvents)Orchestration events track workflow coordination:
TASK_STARTED
Workflow orchestration begins
task_id, total_steps
STEP_COMPLETED
Individual step in workflow completed
task_id, step_id, remaining_steps
VIABLE_STEPS_DISCOVERED
Steps ready for execution identified
task_id, step_ids, batch_size
NO_VIABLE_STEPS
No executable steps found
task_id, reason, blocked_steps
TASK_COMPLETED
Entire workflow finished
task_id, total_duration, success_rate
Observability Events (Tasker::Constants::ObservabilityEvents)
Tasker::Constants::ObservabilityEvents)System-level monitoring events:
Task::ENQUEUE
Task queued for background processing
task_id, queue_name, enqueued_at
Task::START
Task processing started by worker
task_id, worker_id, started_at
Step::PROCESSING
Step processing metrics
task_id, step_id, processing_time, memory_usage
Custom Events
Custom events allow you to define and publish business logic events from your step handlers that can be consumed by subscribers for monitoring, alerting, and notifications. Unlike system events, custom events are declaratively defined by developers and automatically registered.
Creating Custom Events
Tasker provides multiple ways to define custom events with automatic registration:
1. Class-Based Event Configuration (Recommended)
2. YAML-Based Event Configuration
You can also define custom events in your step template YAML files:
Key Features
Automatic Registration: Events are registered when step handlers load - no manual registration required
Namespace Validation: Events must be namespaced (e.g.,
order.fulfilled)Conflict Prevention: Cannot conflict with system events
Reserved Namespaces:
task.*,step.*,workflow.*,observability.*,test.*are reservedComplete Integration: Custom events appear in all discovery methods
Subscriber Compatibility: Work seamlessly with existing subscriber patterns
Publishing Custom Events
From within your step handlers, use the publish_custom_event method:
Custom Event Best Practices
Event Naming
Use namespace.action format:
order.fulfilled,payment.processedChoose descriptive, business-focused names
Avoid technical implementation details in names
Event Payloads
Include relevant business context:
Event Discovery
The event catalog provides comprehensive discovery for both system and custom events:
Using the Event Catalog
Event Documentation Structure
Each event in the catalog includes:
Name: Standard event identifier
Category: Event classification (task, step, workflow, observability, custom)
Description: Human-readable explanation of when the event fires
Payload Schema: Expected data structure with types
Example Payload: Real example of event data
Fired By: Components that publish this event
Print Complete Catalog
Architectural Distinction: Event Subscribers vs Workflow Steps
Critical Design Principle: Event subscribers should handle "collateral" or "secondary" logic - operations that support observability, monitoring, and alerting but are not core business requirements.
Use Event Subscribers For:
Operational Observability: Logging, metrics, telemetry, traces
Alerting & Monitoring: Sentry errors, PagerDuty alerts, operational notifications
Analytics: Business intelligence, usage tracking, performance monitoring
External Integrations: Non-critical third-party service notifications
Use Workflow Steps For:
Business-Critical Operations: Actions that must succeed for the workflow to be considered complete
Operations Requiring:
Idempotency: Can be safely retried without side effects
Retryability: Built-in retry logic with exponential backoff
Explicit Lifecycle Tracking: Success/failure states that matter to the business
Transactional Integrity: Operations that need to be rolled back on failure
Examples of Proper Usage
โ Event Subscriber (Collateral Concerns):
โ Workflow Step (Business Logic):
โ Wrong - Business Logic in Event Subscriber:
Rule of Thumb: If the operation must succeed for the workflow to be considered complete, it should be a workflow step. If it's supporting infrastructure (logging, monitoring, analytics), it should be an event subscriber.
Creating Custom Subscribers
Using the Subscriber Generator
The easiest way to create custom event subscribers is using the built-in generator:
This creates:
A subscriber class extending
Tasker::Events::Subscribers::BaseSubscriberAutomatic method routing based on event names
Complete RSpec test file with realistic patterns
Clear usage instructions and documentation
Manual Subscriber Creation
You can also create subscribers manually to handle both system and custom events:
BaseSubscriber Features
The BaseSubscriber class provides:
Automatic Method Routing:
task.completedโhandle_task_completed,order.fulfilledโhandle_order_fulfilledSafe Data Access:
safe_get(event, :key, default)with type checkingError Handling: Graceful handling of malformed events
Logging: Automatic debug logging for event processing
Flexible Subscription: Subscribe to specific events or event patterns
Subscriber Integration Examples
Your subscribers can handle both system and custom events seamlessly:
Development & Testing
Viewing Events
Testing Both System and Custom Events
Integration Examples
Tasker includes comprehensive integration examples demonstrating real-world usage patterns for both system and custom events. These examples are located in spec/lib/tasker/events/subscribers/examples/ and serve as both documentation and implementation templates.
Available Examples
SentrySubscriber - Error Tracking Integration
Summary
The Tasker Event System provides a unified approach to handling both system workflow events and custom business logic events:
System Events: Automatically published by Tasker for observability and monitoring
Custom Events: Declaratively defined by developers for business logic integration
Unified Discovery: Single catalog and search interface for all events
Seamless Subscribers: Same subscriber patterns work for both event types
Production Ready: Built for real-world monitoring, alerting, and notification scenarios
This comprehensive event system enables you to build robust, observable, and well-integrated workflows that provide visibility into both technical execution and business processes.
Last updated