Skip to content

feat: Use AbortSignal in typescript, add a native timeout capability in python.#2373

Merged
hellovai merged 5 commits intocanaryfrom
hellovai/abort-signal
Aug 27, 2025
Merged

feat: Use AbortSignal in typescript, add a native timeout capability in python.#2373
hellovai merged 5 commits intocanaryfrom
hellovai/abort-signal

Conversation

@hellovai
Copy link
Copy Markdown
Contributor

@hellovai hellovai commented Aug 27, 2025

Summary

Modernizes the abort controller API documentation to use the AbortSignal pattern, aligning with web standards while improving developer experience.

Key Changes:

  • Renamed documentation: "Abort Controllers" → "AbortSignals / Timeouts" to better reflect modern usage patterns
  • Updated TypeScript API: Changed from abortController parameter to abortSignal to align with web standards
  • Added modern timeout pattern for TS: Introduced AbortSignal.timeout(5000) for simple timeout scenarios
  • Enhanced Python support: Added AbortController(timeout_ms=5000) constructor for built-in timeouts
  • Updated cross-references: Fixed all internal links and redirects throughout documentation

Code Examples

Before (old AbortController pattern):

const controller = new AbortController()
const result = await b.ExtractResume(text, {
  abortController: controller  // Old parameter name
})

After (modern AbortSignal pattern):

// Simple timeout approach
const result = await b.ExtractResume(text, {
  abortSignal: AbortSignal.timeout(5000)  // Modern web standard
})

// Manual control when needed
const controller = new AbortController()
const result = await b.ExtractResume(text, {
  abortSignal: controller.signal  // Updated parameter name
})

Python Simplification:

Before (complex manual timeout):

async def with_timeout(operation, timeout_seconds):
    controller = AbortController()
    
    async def run_with_timeout():
        timeout_task = asyncio.create_task(asyncio.sleep(timeout_seconds))
        operation_task = asyncio.create_task(operation(controller))
        
        done, pending = await asyncio.wait(
            [timeout_task, operation_task],
            return_when=asyncio.FIRST_COMPLETED
        )
        
        if timeout_task in done:
            controller.abort()
            raise TimeoutError(f"Operation timed out after {timeout_seconds}s")
        
        return operation_task.result()
    
    return await run_with_timeout()

# Usage
result = await with_timeout(
    lambda ctrl: b.ExtractData(input, baml_options={"abort_controller": ctrl}),
    5  # 5 second timeout
)

After (built-in timeout support):

# Much simpler with built-in timeout
controller = AbortController(timeout_ms=5000)  # Automatic timeout
result = await b.ExtractData(input, baml_options={"abort_controller": controller})

Impact

This refactor eliminates the need for complex asyncio.wait() and manual task management by moving timeout functionality directly into the API, making it much cleaner and less error-prone while following modern web standards.

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

@vercel
Copy link
Copy Markdown

vercel Bot commented Aug 27, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
promptfiddle Ready Ready Preview Comment Aug 27, 2025 6:33am

@entelligence-ai-pr-reviews
Copy link
Copy Markdown

⚠️ Trial Period Expired ⚠️

Your trial period has expired. To continue using this feature, please upgrade to a paid plan here or book a time to chat here.

@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:13 — with GitHub Actions Inactive
@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:13 — with GitHub Actions Inactive
@github-actions
Copy link
Copy Markdown

@ellipsis-dev
Copy link
Copy Markdown
Contributor

ellipsis-dev Bot commented Aug 27, 2025

⚠️ This PR is too big for Ellipsis, but support for larger PRs is coming soon. If you want us to prioritize this feature, let us know at help@ellipsis.dev


Generated with ❤️ by ellipsis.dev

@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:20 — with GitHub Actions Inactive
@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:20 — with GitHub Actions Inactive
@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:20 — with GitHub Actions Inactive
@github-actions
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown

@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:43 — with GitHub Actions Inactive
@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:43 — with GitHub Actions Inactive
@github-actions
Copy link
Copy Markdown

@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:55 — with GitHub Actions Inactive
@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:55 — with GitHub Actions Inactive
@hellovai hellovai temporarily deployed to boundary-tools-dev August 27, 2025 05:55 — with GitHub Actions Inactive
@hellovai hellovai enabled auto-merge August 27, 2025 05:56
@github-actions
Copy link
Copy Markdown

@hellovai hellovai added this pull request to the merge queue Aug 27, 2025
@hellovai hellovai disabled auto-merge August 27, 2025 06:05
Merged via the queue into canary with commit a12ba5a Aug 27, 2025
24 of 25 checks passed
@hellovai hellovai deleted the hellovai/abort-signal branch August 27, 2025 06:15
@github-actions
Copy link
Copy Markdown

github-merge-queue Bot pushed a commit that referenced this pull request Aug 27, 2025
This is likely to be more compatible with LLM coding agents, since this
is the naming convention pretty much all standard Node APIs abide by:
fetch, fs.promises, child_process.spawn, setTimeout, addEventListener,
Axios, Got (HTTP client), p-queue, Puppeteer. Node that use other
conventions tend to be legacy or non-standard (e.g. axios used
`cancelToken` before `signal: AbortSignal` was added to the standard
library), although interestingly both the AWS and Azure SDKs do use
`abortSignal: AbortSignal`.

The other reason I think we had for `abortSignal: AbortSignal` instead
of `signal: AbortSignal` was for cross-language ergonomics, but a
cursory look at other SDKs (e.g. aws and azure) tells me that they
prioritize using the most language-native convention available (e.g.
`cancellationToken` in C#) and I know Vaibhav and I both agree that the
Python protobuf API is one of the least ergonomic APIs in existence
because of the cross-language inconsistency.

Followup to #2357 and #2373 - many thanks to @trojanowski for being a
super active and involved user and pushing us to have a more ergonomic
API!
cg-jl pushed a commit that referenced this pull request Aug 28, 2025
…in python. (#2373)

## Summary
Modernizes the abort controller API documentation to use the AbortSignal
pattern, aligning with web standards while improving developer
experience.

**Key Changes:**
- **Renamed documentation**: "Abort Controllers" → "AbortSignals /
Timeouts" to better reflect modern usage patterns
- **Updated TypeScript API**: Changed from `abortController` parameter
to `abortSignal` to align with web standards
- **Added modern timeout pattern for TS**: Introduced
`AbortSignal.timeout(5000)` for simple timeout scenarios
- **Enhanced Python support**: Added `AbortController(timeout_ms=5000)`
constructor for built-in timeouts
- **Updated cross-references**: Fixed all internal links and redirects
throughout documentation

## Code Examples

### Before (old AbortController pattern):
```typescript
const controller = new AbortController()
const result = await b.ExtractResume(text, {
  abortController: controller  // Old parameter name
})
```

### After (modern AbortSignal pattern):
```typescript
// Simple timeout approach
const result = await b.ExtractResume(text, {
  abortSignal: AbortSignal.timeout(5000)  // Modern web standard
})

// Manual control when needed
const controller = new AbortController()
const result = await b.ExtractResume(text, {
  abortSignal: controller.signal  // Updated parameter name
})
```

### Python Simplification:

**Before (complex manual timeout):**
```python
async def with_timeout(operation, timeout_seconds):
    controller = AbortController()
    
    async def run_with_timeout():
        timeout_task = asyncio.create_task(asyncio.sleep(timeout_seconds))
        operation_task = asyncio.create_task(operation(controller))
        
        done, pending = await asyncio.wait(
            [timeout_task, operation_task],
            return_when=asyncio.FIRST_COMPLETED
        )
        
        if timeout_task in done:
            controller.abort()
            raise TimeoutError(f"Operation timed out after {timeout_seconds}s")
        
        return operation_task.result()
    
    return await run_with_timeout()

# Usage
result = await with_timeout(
    lambda ctrl: b.ExtractData(input, baml_options={"abort_controller": ctrl}),
    5  # 5 second timeout
)
```

**After (built-in timeout support):**
```python
# Much simpler with built-in timeout
controller = AbortController(timeout_ms=5000)  # Automatic timeout
result = await b.ExtractData(input, baml_options={"abort_controller": controller})
```

## Impact
This refactor eliminates the need for complex `asyncio.wait()` and
manual task management by moving timeout functionality directly into the
API, making it much cleaner and less error-prone while following modern
web standards.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
cg-jl pushed a commit that referenced this pull request Aug 28, 2025
This is likely to be more compatible with LLM coding agents, since this
is the naming convention pretty much all standard Node APIs abide by:
fetch, fs.promises, child_process.spawn, setTimeout, addEventListener,
Axios, Got (HTTP client), p-queue, Puppeteer. Node that use other
conventions tend to be legacy or non-standard (e.g. axios used
`cancelToken` before `signal: AbortSignal` was added to the standard
library), although interestingly both the AWS and Azure SDKs do use
`abortSignal: AbortSignal`.

The other reason I think we had for `abortSignal: AbortSignal` instead
of `signal: AbortSignal` was for cross-language ergonomics, but a
cursory look at other SDKs (e.g. aws and azure) tells me that they
prioritize using the most language-native convention available (e.g.
`cancellationToken` in C#) and I know Vaibhav and I both agree that the
Python protobuf API is one of the least ergonomic APIs in existence
because of the cross-language inconsistency.

Followup to #2357 and #2373 - many thanks to @trojanowski for being a
super active and involved user and pushing us to have a more ergonomic
API!
cg-jl pushed a commit that referenced this pull request Aug 28, 2025
This is likely to be more compatible with LLM coding agents, since this
is the naming convention pretty much all standard Node APIs abide by:
fetch, fs.promises, child_process.spawn, setTimeout, addEventListener,
Axios, Got (HTTP client), p-queue, Puppeteer. Node that use other
conventions tend to be legacy or non-standard (e.g. axios used
`cancelToken` before `signal: AbortSignal` was added to the standard
library), although interestingly both the AWS and Azure SDKs do use
`abortSignal: AbortSignal`.

The other reason I think we had for `abortSignal: AbortSignal` instead
of `signal: AbortSignal` was for cross-language ergonomics, but a
cursory look at other SDKs (e.g. aws and azure) tells me that they
prioritize using the most language-native convention available (e.g.
`cancellationToken` in C#) and I know Vaibhav and I both agree that the
Python protobuf API is one of the least ergonomic APIs in existence
because of the cross-language inconsistency.

Followup to #2357 and #2373 - many thanks to @trojanowski for being a
super active and involved user and pushing us to have a more ergonomic
API!
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