Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(py-isolation-saga): document wait_for cancel semantics on timeout#2174

Merged
imran-siddique merged 1 commit into
microsoft:mainfrom
aegis-initiative:fix/py-isolation-saga-timeout-cancel-semantics
May 12, 2026
Merged

fix(py-isolation-saga): document wait_for cancel semantics on timeout#2174
imran-siddique merged 1 commit into
microsoft:mainfrom
aegis-initiative:fix/py-isolation-saga-timeout-cancel-semantics

Conversation

@finnoybu

Copy link
Copy Markdown
Contributor

Summary

saga/orchestrator.py's SagaOrchestrator.execute_step and .compensate both wrap their callable in asyncio.wait_for(callable, timeout=step.timeout_seconds). The standing audit question was whether wait_for awaits the cancellation it issues, or just signals it and moves on.

CPython's asyncio.wait_for does wait for the cancellation to complete before raising TimeoutError (see Python docs). Cooperative executors with await points get a chance to release resources. But:

  • Executors with no await points (synchronous CPU work inside an async def) are not cancellable by Python at all — the timeout only fires once the executor next yields control.
  • Callers needing hard-kill semantics must run such executors in a process or thread pool and arrange external termination.

The behaviour is correct as-is; what's missing is the contract being documented for callers writing executors.

Change

Add a Cancellation semantics on timeout: block to execute_step's docstring naming the cooperative-cancel contract and the two failure modes. Cross-reference from compensate's docstring.

Pure documentation change — no behaviour delta.

Tests

$ PYTHONPATH=src python -m pytest tests/unit/test_saga.py tests/unit/test_saga_improvements.py -q
32 passed, 12 skipped in 0.35s

No new tests needed (documentation change).

Test plan

  • CI passes
  • No behaviour change in saga step / compensation paths

Surfaced during independent audit conducted by @finnoybu (Ken Tannenbaum, AEGIS Initiative); [LOW, Python Isolation].

`SagaOrchestrator.execute_step` and `.compensate` both wrap their
callable in `asyncio.wait_for(callable, timeout=step.timeout_seconds)`.
The standing audit question was whether wait_for *awaits* the
cancellation it issues, or just signals it and moves on.

CPython's `asyncio.wait_for` does in fact wait for the cancellation to
complete before raising `TimeoutError`. Cooperative executors with
`await` points get a chance to release resources. But:

  - Executors with no `await` points (synchronous CPU work inside an
    `async def`) are not cancellable by Python at all — the timeout
    only fires once the executor next yields control.
  - Callers needing hard-kill semantics must run such executors in a
    process or thread pool and arrange external termination.

Document this contract on `execute_step`; cross-reference from
`compensate`. No behaviour change — pure docstring clarification.
@github-actions github-actions Bot added the agent-hypervisor agent-hypervisor package label May 12, 2026
@github-actions

Copy link
Copy Markdown
🤖 AI Agent: code-reviewer — View details

No issues found. Clean change.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: test-generator — View details

Test coverage looks good. No gaps identified.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: security-scanner — View details

No security issues found.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: docs-sync-checker — Docs Sync

Docs Sync

  • execute_step() in saga/orchestrator.py -- missing docstring for cancellation semantics on timeout
  • compensate() in saga/orchestrator.py -- missing cross-reference to execute_step's updated docstring
  • CHANGELOG.md -- missing entry for behavioral changes regarding cancellation semantics documentation

@github-actions github-actions Bot added the size/S Small PR (< 50 lines) label May 12, 2026
@github-actions

Copy link
Copy Markdown
🤖 AI Agent: breaking-change-detector — View details

No breaking changes detected.

@github-actions

Copy link
Copy Markdown

🟡 Contributor Check: MEDIUM

Check Result
Profile MEDIUM
Credential NONE
Overall MEDIUM

Automated check by AGT Contributor Check.

@github-actions github-actions Bot added the needs-review:MEDIUM Contributor check flagged MEDIUM risk label May 12, 2026
@github-actions

Copy link
Copy Markdown

PR Review Summary

Check Status Details
🔍 Code Review ✅ Passed No issues found
🛡️ Security Scan ✅ Passed No issues found
🔄 Breaking Changes ✅ Passed No issues found
📝 Docs Sync ✅ Completed Analysis complete
🧪 Test Coverage ✅ Completed Analysis complete

Verdict: ✅ Ready for human review

@imran-siddique imran-siddique merged commit 71d32ae into microsoft:main May 12, 2026
13 of 14 checks passed
MohammadHaroonAbuomar pushed a commit to MohammadHaroonAbuomar/agt-acs that referenced this pull request Jun 1, 2026
…microsoft#2174)

`SagaOrchestrator.execute_step` and `.compensate` both wrap their
callable in `asyncio.wait_for(callable, timeout=step.timeout_seconds)`.
The standing audit question was whether wait_for *awaits* the
cancellation it issues, or just signals it and moves on.

CPython's `asyncio.wait_for` does in fact wait for the cancellation to
complete before raising `TimeoutError`. Cooperative executors with
`await` points get a chance to release resources. But:

  - Executors with no `await` points (synchronous CPU work inside an
    `async def`) are not cancellable by Python at all — the timeout
    only fires once the executor next yields control.
  - Callers needing hard-kill semantics must run such executors in a
    process or thread pool and arrange external termination.

Document this contract on `execute_step`; cross-reference from
`compensate`. No behaviour change — pure docstring clarification.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-hypervisor agent-hypervisor package needs-review:MEDIUM Contributor check flagged MEDIUM risk size/S Small PR (< 50 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants