feat(executor): add async function and method execution support#42
feat(executor): add async function and method execution support#42
Conversation
Add support for executing both sync and async functions/methods in FunctionExecutor and ClassExecutor. Uses inspect.iscoroutinefunction() to detect async callables and asyncio.run() to execute them. Changes: - FunctionExecutor: Added async function support with detection and execution - ClassExecutor: Added async method support with same pattern - Comprehensive test coverage for async execution patterns including: - Basic async functions/methods - Async with await operations - Dict returns (GPU worker pattern) - Instance persistence across async calls - Mixed sync/async methods in same class
There was a problem hiding this comment.
Pull Request Overview
This PR adds support for executing both synchronous and asynchronous functions and methods in the worker-tetra execution engine. The implementation uses inspect.iscoroutinefunction() to detect async callables and asyncio.run() to execute them, enabling GPU workers and other use cases that require async execution patterns.
Key Changes:
- Added async execution support to
FunctionExecutorandClassExecutorwith automatic detection - Comprehensive test coverage for async patterns including await operations, dict returns, and mixed sync/async methods
- Added
DEVELOPMENT.mdguide for contributors
Reviewed Changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/function_executor.py |
Added async function detection and execution using inspect.iscoroutinefunction() and asyncio.run() |
src/class_executor.py |
Added async method detection and execution with same pattern as function executor |
tests/unit/test_function_executor.py |
Added comprehensive test suite for async function execution patterns |
tests/unit/test_class_executor.py |
Added comprehensive test suite for async method execution with instance persistence |
DEVELOPMENT.md |
Added complete developer guide covering setup, workflow, testing, and contribution guidelines |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address PR #42 Copilot feedback about asyncio.run() usage. The previous implementation used asyncio.run() unconditionally, which raises RuntimeError when called from within a running event loop (e.g., nested async calls). This could break in scenarios where: - Handler becomes async in the future - Users nest remote function calls - Execution happens in unexpected async contexts Changes: - Detect running event loop with asyncio.get_running_loop() - Use asyncio.run() when no loop is running (current path) - Use loop.run_until_complete() when loop exists - Applies to both FunctionExecutor and ClassExecutor This future-proofs the async execution logic while maintaining backward compatibility with current synchronous execution context. Addresses: #42 (comment) Addresses: #42 (comment)
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address PR #42 Copilot feedback (round 2) about async/await architecture. Root cause: Handler is async (RunPod supports async handlers) which means an event loop is running when executors execute. Using loop.run_until_complete() from within a running loop causes deadlock. Solution: Make entire execution chain async with proper await: - handler (async) → ExecuteFunction (async) → executors (async) → user funcs Changes: - FunctionExecutor.execute(): Made async, await async functions directly - ClassExecutor.execute_class_method(): Made async, await async methods directly - RemoteExecutor: Added await to executor calls - All tests: Made async and added await to executor calls This eliminates event loop conflicts by using proper async/await chain instead of trying to manage event loops manually. Works correctly with RunPod's async handler support. Fixes: #42 (comment) Fixes: #42 (comment) Addresses: Copilot follow-up comments about loop.run_until_complete() deadlock
Add support for executing both sync and async functions/methods in
FunctionExecutor and ClassExecutor. Uses inspect.iscoroutinefunction()
to detect async callables and asyncio.run() to execute them.
Changes:
DEVELOPMENT.mdguide