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

  1. Events::Publisher - Centralized event publishing using dry-events

  2. EventPublisher Concern - Clean interface for business logic (publish_step_completed, publish_custom_event)

  3. EventPayloadBuilder - Standardized payload creation for consistent data structures

  4. Event Catalog - Complete event discovery and documentation system (system + custom events)

  5. BaseSubscriber - Foundation for creating custom event subscribers

  6. TelemetrySubscriber - Production OpenTelemetry integration

  7. 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)

Task lifecycle events track the overall progress of workflow execution:

Event
Description
Typical Payload

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)

Step-level events provide detailed execution tracking:

Event
Description
Typical Payload

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)

Orchestration events track workflow coordination:

Event
Description
Typical Payload

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)

System-level monitoring events:

Event
Description
Typical Payload

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:

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 reserved

  • Complete 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.processed

  • Choose 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


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::BaseSubscriber

  • Automatic 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_fulfilled

  • Safe Data Access: safe_get(event, :key, default) with type checking

  • Error 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