> ## Documentation Index
> Fetch the complete documentation index at: https://hyrex.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tasks

> Define and execute distributed tasks with TypeScript

Tasks are the fundamental unit of work in Hyrex. They are TypeScript functions that can be executed asynchronously by workers, with automatic retry handling, monitoring, and durability.

## Basic Task Definition

Define a task using the `hy.task()` method:

```typescript theme={null}
import { HyrexRegistry } from '@hyrex/hyrex';

const hy = new HyrexRegistry();

interface ProcessInput {
    file_path: string;
    options: Record<string, any>;
}

const processFile = hy.task({
    name: 'processFile',
    func: async (input: ProcessInput) => {
        // Task logic
        console.log(`Processing ${input.file_path}`);
        return { status: 'completed', file: input.file_path };
    }
});
```

<Note>
  Tasks can accept either zero arguments or one JSON-serializable argument. The return value must also be JSON-serializable or void.
</Note>

## Task Configuration

Configure task behavior with the config object:

```typescript theme={null}
const configuredTask = hy.task({
    name: 'configuredTask',
    config: {
        queue: 'processing',           // Target queue
        maxRetries: 3,                // Retry attempts (0-10, default: 3)
        timeoutSeconds: 300,          // Timeout in seconds
        priority: 5,                  // 1-10 (higher = more important, default: 3)
        cron: '0 * * * *',           // Optional cron schedule
        idempotencyKey: 'unique-key'  // Prevent duplicate executions
    },
    func: async (data: any) => {
        // Process with specific configuration
        return { processed: true };
    }
});
```

### Configuration Options

* **queue**: Route tasks to specific worker pools (default: "default")
* **maxRetries**: Number of retry attempts on failure (0-10, default: 3)
* **timeoutSeconds**: Maximum execution time before timeout
* **priority**: Task priority from 1-10 (default: 3)
* **cron**: Cron expression for scheduled tasks
* **idempotencyKey**: Unique key to prevent duplicate task executions

## Sending Tasks

Queue tasks for asynchronous execution:

```typescript theme={null}
// Send with default configuration
const taskId = await processFile.send({
    file_path: '/data/input.csv',
    options: { format: 'csv' }
});

// Override configuration at runtime
const urgentTaskId = await processFile.withConfig({
    queue: 'high-priority',
    maxRetries: 5
}).send(input);

console.log(`Task ID: ${taskId}`);
```

## Task Context

Access metadata about the current task execution:

```typescript theme={null}
import { getHyrexContext } from '@hyrex/hyrex';

const taskWithContext = hy.task({
    name: 'taskWithContext',
    func: async (data: any) => {
        // Get current task metadata
        const ctx = getHyrexContext();
        
        console.log(`Task ID: ${ctx.taskId}`);
        console.log(`Attempt: ${ctx.attemptNumber + 1}/${ctx.maxRetries + 1}`);
        console.log(`Queue: ${ctx.queue}`);
        console.log(`Parent ID: ${ctx.parentId}`);
        
        // Your task logic here
        return { processedBy: ctx.taskId };
    }
});
```

### Context Properties

* **taskId**: Unique identifier for the task
* **durableId**: Persistent identifier for durable task storage
* **rootId**: ID of the root task in the task tree
* **parentId**: ID of the parent task (null if root)
* **workflowRunId**: ID of the workflow run (if part of workflow)
* **taskName**: Name of the task being executed
* **queue**: Queue name where task is processed
* **priority**: Task priority level
* **attemptNumber**: Current attempt number (0-based)
* **maxRetries**: Maximum retry attempts configured
* **timeoutSeconds**: Timeout configuration
* **executorId**: ID of the executor processing this task

## Error Handling

Tasks can throw errors to trigger retries:

```typescript theme={null}
const taskWithRetries = hy.task({
    name: 'taskWithRetries',
    config: {
        maxRetries: 3
    },
    func: async (data: any) => {
        try {
            // Attempt operation
            const result = await externalApiCall(data);
            return result;
        } catch (error) {
            if (error instanceof TemporaryError) {
                // This will trigger a retry
                throw error;
            } else if (error instanceof PermanentError) {
                // This will not retry
                return { error: error.message, status: 'failed' };
            }
            throw error;
        }
    }
});
```

### Retry Behavior

* Throwing any exception triggers a retry (if retries remain)
* Return a value to complete the task (even with errors)
* Retries use exponential backoff by default

## Input Validation

Use Zod schemas for type-safe input validation:

```typescript theme={null}
import { z } from 'zod';

const EmailSchema = z.object({
    to: z.string().email(),
    subject: z.string(),
    body: z.string()
});

const sendEmail = hy.task({
    name: 'sendEmail',
    argSchema: EmailSchema,
    func: async (input) => {
        // Input is automatically validated against schema
        // TypeScript knows input matches EmailSchema
        console.log(`Sending email to ${input.to}`);
        return { sent: true };
    }
});

// This will validate at runtime
await sendEmail.send({
    to: 'user@example.com',
    subject: 'Hello',
    body: 'Welcome!'
});
```

## Task Results

The `send()` method returns a task ID immediately:

```typescript theme={null}
// Send a task
const taskId = await processFile.send(context);
console.log(`Task queued with ID: ${taskId}`);

// Note: The TypeScript SDK returns only the task ID
// Task status and results must be monitored through Hyrex Studio or logs
```

## Best Practices

1. **Use Type-Safe Interfaces**
   ```typescript theme={null}
   interface OrderContext {
       orderId: number;
       customerEmail: string;
       items: Array<{ sku: string; quantity: number }>;
   }

   const processOrder = hy.task({
       name: 'processOrder',
       func: async (context: OrderContext) => {
           // TypeScript ensures type safety
           return { orderId: context.orderId };
       }
   });
   ```

2. **Set Appropriate Timeouts**
   ```typescript theme={null}
   // Fast operations
   config: { timeoutSeconds: 30 }

   // Long-running jobs
   config: { timeoutSeconds: 3600 }
   ```

3. **Design for Idempotency**
   ```typescript theme={null}
   const processPayment = hy.task({
       name: 'processPayment',
       config: {
           idempotencyKey: 'payment-123'  // Prevents duplicate charges
       },
       func: async (context: PaymentContext) => {
           // Check if already processed
           const existing = await checkPaymentStatus(context.paymentId);
           if (existing) {
               return existing;
           }
           
           // Process payment
           const result = await chargeCard(context);
           await savePaymentResult(context.paymentId, result);
           return result;
       }
   });
   ```

4. **Handle Errors Gracefully**
   ```typescript theme={null}
   const fetchData = hy.task({
       name: 'fetchData',
       config: { maxRetries: 3 },
       func: async (context: FetchContext) => {
           try {
               return await fetchFromApi(context.url);
           } catch (error: any) {
               if (error.code === 'RATE_LIMIT') {
                   // Retry with backoff
                   throw error;
               } else if (error.code === 'INVALID_DATA') {
                   // Don't retry, return error
                   return { error: error.message, status: 'invalid_data' };
               }
               throw error;
           }
       }
   });
   ```

## Next Steps

<CardGroup cols={2}>
  <Card title="Workflows" icon="diagram-project" href="/reference/typescript/workflows">
    Orchestrate multiple tasks
  </Card>

  <Card title="Queues" icon="layer-group" href="/reference/typescript/queues">
    Route tasks to worker pools
  </Card>

  <Card title="Retries" icon="rotate" href="/reference/typescript/retries">
    Configure retry strategies
  </Card>
</CardGroup>
