brainstorming
Structured design dialogue that validates ideas before implementation begins.
cancel-async-tasks
Guidance for implementing asyncio task cancellation with proper cleanup, especially for handling keyboard interrupts (Ctrl+C). This skill should be used when tasks involve asyncio cancellation, signal handling, or graceful shutdown of concurrent Python tasks.
Full skill instructions
This skill provides guidance for implementing proper cancellation handling in Python asyncio code, with particular focus on keyboard interrupt (Ctrl+C) handling and graceful cleanup.
Understanding the difference is critical:
BaseException raised in the main thread when Ctrl+C is pressed. It does NOT propagate into async coroutines directly.Exception raised inside coroutines when task.cancel() is called. This IS what coroutines receive during cancellation.Critical Insight: Placing except KeyboardInterrupt inside an async function will NOT catch Ctrl+C. The interrupt is raised at the event loop level, not within coroutines.
To properly handle Ctrl+C in asyncio:
loop.add_signal_handler() to register SIGINT/SIGTERM handlersasyncio.run() in a try/except at the synchronous entry pointCancelledError in coroutinesRegister signal handlers at the event loop level to trigger graceful shutdown:
1. Get the event loop
2. Add signal handlers for SIGINT and SIGTERM
3. In the signal handler, cancel all running tasks
4. In coroutines, catch CancelledError to perform cleanup
Wrap the async entry point to catch KeyboardInterrupt synchronously:
1. Define the async main logic
2. In a synchronous wrapper, call asyncio.run() inside try/except
3. Catch KeyboardInterrupt in the synchronous code
4. Handle cleanup or re-raise as needed
Use asyncio.TaskGroup for structured concurrency:
1. Use async with asyncio.TaskGroup() for task management
2. TaskGroup handles cancellation propagation automatically
3. Catch ExceptionGroup for handling multiple failures
Do NOT rely solely on timeout-based cancellation testing. Verify with actual signals:
import os
import signal
# Simulate Ctrl+C in tests
os.kill(os.getpid(), signal.SIGINT)
Create observable side effects to confirm cleanup runs:
asyncio.timeout)task.cancel() callsTest that exceptions from individual tasks are properly collected and reported, not silently swallowed.
Wrong:
async def my_coroutine():
try:
await some_operation()
except KeyboardInterrupt: # Will NOT catch Ctrl+C!
await cleanup()
Correct:
async def my_coroutine():
try:
await some_operation()
except asyncio.CancelledError: # This WILL be raised on cancellation
await cleanup()
raise # Re-raise to propagate cancellation
Swallowing CancelledError prevents proper cancellation propagation. Always re-raise after cleanup unless there's a specific reason not to.
Testing with asyncio.timeout() or asyncio.wait_for() does NOT verify keyboard interrupt handling. These trigger TimeoutError, not the same path as SIGINT.
Cleanup code itself can be cancelled if it awaits. Use asyncio.shield() for critical cleanup:
async def cleanup():
await asyncio.shield(critical_cleanup_operation())
Always validate inputs:
asyncio.gather(return_exceptions=True) collects exceptions but doesn't handle them. Results must be inspected for exception instances.
add_signal_handler doesn't work on Windows for SIGINT; use alternative approachesloop.add_signal_handler() works for SIGINT, SIGTERMadd_signal_handler() is limited; only works for SIGINT in some casessignal.signal() before starting the event loopStructured design dialogue that validates ideas before implementation begins.
Comprehensive design intelligence for web and mobile UI/UX across 10 technology stacks.
Comprehensive implementation plans for multi-step tasks, breaking down specs into bite-sized, testable steps.
Introduction to the obra skills system with mandatory skill invocation rules and best practices.
Execute a written implementation plan with critical review and task checkpoints.
Delegate independent tasks to specialized agents working concurrently with isolated context.
Isolated git worktrees with smart directory selection and safety verification.
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
Plan searchable and shareable content that drives traffic, builds authority, and generates leads.
README-first repository scanner that extracts commands and classifies reproduction candidates without executing them.
Brainstorm and prioritize marketing strategies tailored to your SaaS stage, budget, and goals.
Plan and optimize your website's page hierarchy, navigation, URL structure, and internal linking.
The world's fastest calendar for remote work
Capture, organize, and utilize your knowledge effortlessly.
Instant Summaries of Audio & Video Interviews with AnySummary
Transform PDFs into engaging mind maps.
Chat with any PDF instantly
Create an optimal daily plan using your voice
A productivity platform to centralize organizational knowledge and workflows with contextual AI assistance.
AskYourPDF Pricing Plans: Tailored to Your Needs