Skip to content

Conversation

micovi
Copy link

@micovi micovi commented Aug 5, 2025

Cron Device Task List Enhancement

Overview

This PR enhances the [email protected] device to provide comprehensive task listing functionality with detailed metadata about active cron tasks. The /[email protected]/list endpoint now returns rich information about each scheduled task, including type, path, interval, and creation timestamp.

Motivation

Previously, operators had limited visibility into active cron tasks on their HyperBEAM nodes. This enhancement addresses the need for better observability and debugging capabilities by providing detailed information about all scheduled tasks.

Changes Made

1. Added List Endpoint (list/3)

File: src/dev_cron.erl

Added a new list/3 function that:

  • Queries all registered names via hb_name:all/0
  • Filters for entries matching {<<"[email protected]">>, TaskID} pattern
  • Retrieves metadata from worker processes using a dual approach:
    • Primary: Non-blocking process dictionary lookup via erlang:process_info/2
    • Fallback: Message passing with timeout for compatibility
  • Returns formatted JSON response with task details

2. Enhanced Worker Processes with Metadata

Once Worker (once_worker/4)

  • Now accepts CreatedAt timestamp parameter (in milliseconds)
  • Stores metadata in process dictionary for instant access
  • Executes task immediately after storing metadata
  • Metadata includes: type, path, created_at

Every Worker Loop (every_worker_loop/6)

  • Extended to accept CreatedAt timestamp (milliseconds) and IntervalString parameters
  • Stores metadata in process dictionary at start of each loop
  • Implements wait_with_info/1 for responsive info handling during sleep
  • Uses monotonic time to accurately track remaining sleep time when interrupted
  • Metadata includes: type, path, interval, interval_ms, created_at

3. Info Request Handling

New Functions:

  • wait_with_info/1: Allows every workers to respond to info requests while sleeping, using monotonic time for accuracy

4. Updated Module Exports and Documentation

  • Added list to module exports
  • Updated info/0 to include list in exports
  • Updated info/3 to document the list endpoint: <<"list">> => <<"List all active cron tasks">>

5. Comprehensive Test Coverage

Added list_tasks_test/0 that:

  • Cleans up any existing cron tasks before testing
  • Creates an every task (since once tasks execute immediately)
  • Verifies the task appears in the list with correct metadata
  • Validates all metadata fields (type, path, interval, created_at, etc.)
  • Properly cleans up after testing
  • Tests use millisecond timestamps consistent with the codebase

API Response Format

Before

The list endpoint did not exist.

After

{
  "status": 200,
  "body": [
    {
      "task_id": "ks4Gebwlhafrv89iOAYpEtJkg9QgEiEC80RH0xr-A_o",
      "pid": "<0.1184.0>",
      "type": "every",
      "path": "/[email protected]/now",
      "interval": "30-seconds",
      "interval_ms": 30000,
      "created_at": 1735251600000
    },
    {
      "task_id": "bXjtHTVYw3CznxqpB6xBrJpBKvBX0-rPloG-Gffei9A",
      "pid": "<0.1185.0>",
      "type": "once",
      "path": "/[email protected]/update_state",
      "created_at": 1735251605000
    }
  ]
}

Technical Implementation Details

Process Dictionary Approach

To ensure responsive metadata retrieval even when workers are busy executing tasks, metadata is stored in the process dictionary. This allows the list function to retrieve information without blocking, using erlang:process_info(Pid, dictionary). This approach follows patterns used in other parts of the codebase like hb_ao.erl.

Time Management

  • All timestamps use erlang:system_time(millisecond) for consistency with the codebase
  • The wait_with_info/1 function uses erlang:monotonic_time(millisecond) to accurately track elapsed time when handling info requests
  • This ensures workers maintain their scheduled intervals even when interrupted by metadata queries

Graceful Degradation

If metadata cannot be retrieved (process busy, not yet initialized, etc.), the response includes minimal information with "type": "unknown" and "path": "unknown" to indicate the issue.

Benefits

  1. Enhanced Observability: Operators can now see all active cron tasks with detailed information
  2. Better Debugging: Task paths, types, and creation times help identify and troubleshoot issues
  3. Non-Blocking: Uses process dictionary for instant metadata access without blocking workers
  4. Backward Compatible: Existing cron functionality remains unchanged

Testing

All existing tests pass, plus new test coverage for:

  • List endpoint functionality
  • Metadata retrieval from both once and every workers
  • Millisecond timestamp handling
  • Edge cases (timeouts, missing metadata)
  • Process dictionary access patterns

Run tests with:

rebar3 eunit --module=dev_cron

Key Implementation Decisions

Timestamp Consistency

  • Raw millisecond timestamps are consistent with hb:now() and all timing operations

Unified Worker Behavior

  • Both once and every workers store metadata identically in process dictionary

Non-blocking Design

  • Primary metadata retrieval via erlang:process_info(Pid, dictionary) - instant and non-blocking
  • Fallback to message passing only when process dictionary is not available
  • 50ms timeout ensures list endpoint remains responsive

Migration Notes

No migration required. The enhancement is fully backward compatible and adds new functionality without modifying existing behavior.

│                                                                                      │
│   - Added list/3 function to query all registered cron tasks                         │
│   - Enhanced once_worker and every_worker_loop with metadata storage                 │
│   - Store task metadata in process dictionary for non-blocking access                │
│   - Metadata includes type, path, interval, and creation timestamp                   │
│   - Use millisecond timestamps consistent with codebase patterns                     │
│   - Added comprehensive test coverage for list functionality                         │
│   - Unified info request handling between once and every workers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant