Skip to content

Conversation

@thorwhalen
Copy link
Member

No description provided.

claude and others added 3 commits November 19, 2025 01:16
Implements boilerplate-minimal async task processing for long-running operations.
Clients can now choose between synchronous (blocking) and asynchronous (task-based) execution.

## Key Features

### Core Async Functionality
- Task-based async execution with unique task IDs
- Client-controlled sync/async mode via query param or header
- Standard HTTP patterns for task management
- Built-in task status tracking and result retrieval
- Support for both sync and async Python functions

### Task Management
- Automatic task management endpoints:
  - GET /tasks/ - List all tasks
  - GET /tasks/{id} - Get complete task info
  - GET /tasks/{id}/status - Get task status
  - GET /tasks/{id}/result - Get result (with optional wait)
  - DELETE /tasks/{id} - Cancel/delete task

### Flexible Configuration
- Simple case: just specify `async_funcs=['function_name']`
- Advanced: per-function TaskConfig with custom executors
- Multiple execution backends:
  - ThreadPoolTaskExecutor (I/O-bound tasks)
  - ProcessPoolTaskExecutor (CPU-bound tasks)
  - Custom executors via TaskExecutor interface
- Pluggable storage backends via TaskStore interface
- TTL-based result expiration

### Developer Experience
- Convention-based with escape hatches
- Zero external dependencies (uses stdlib)
- Fully backward compatible
- Comprehensive test coverage (16 tests)
- Ready for au package integration

## Implementation Details

### New Modules
- `qh/async_tasks.py` - Core task management, stores, and executors
- `qh/async_endpoints.py` - HTTP endpoints for task management
- `qh/async_example.py` - Comprehensive usage examples
- `qh/tests/test_async_tasks.py` - Full test suite

### Modified Modules
- `qh/app.py` - Added async_funcs and async_config parameters to mk_app
- `qh/config.py` - Added async_config field to RouteConfig
- `qh/endpoint.py` - Added async execution logic to endpoint creation
- `qh/__init__.py` - Exported async task classes and functions

### API Examples

Simple case:
```python
app = mk_app([expensive_func], async_funcs=['expensive_func'])
# POST /expensive_func?async=true -> Returns task_id
```

Advanced configuration:
```python
app = mk_app(
    [cpu_func, io_func],
    async_funcs=['cpu_func', 'io_func'],
    async_config={
        'cpu_func': TaskConfig(
            executor=ProcessPoolTaskExecutor(max_workers=4),
            ttl=3600
        ),
        'io_func': TaskConfig(async_mode='always')
    }
)
```

## Design Philosophy

Following qh's "convention over configuration" approach:
- Default conventions use thread pools and query params
- Explicit configuration available for all aspects
- Built on standard patterns (HTTP 202 Accepted, polling)
- No external dependencies required (au integration optional)

## Testing

All 16 async tests passing:
- Basic sync/async execution
- Task status and result retrieval
- Failed task handling
- Multiple configuration modes (query, header, always)
- TTL and cleanup
- Native async functions
- Task management endpoints
- Multiple function support

## Documentation

Comprehensive README update with:
- Quickstart examples
- Advanced configuration
- Real-world use cases
- Migration guide
- Comparison with other frameworks
- au package integration guide

## Future Enhancements

The implementation is designed to support:
- Integration with au package for distributed execution
- Custom storage backends (Redis, database, etc.)
- WebSocket-based result streaming
- Task prioritization and scheduling
- Task dependencies and workflows
@thorwhalen thorwhalen merged commit b58a190 into master Nov 19, 2025
0 of 6 checks passed
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.

3 participants