Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Fix ReAwaitable to support concurrent await calls (#2108) #2150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
Loading
from

Conversation

AdrianAcala
Copy link

@AdrianAcala AdrianAcala commented May 30, 2025

Fix ReAwaitable to support concurrent await calls

This PR adds thread-safe caching with asyncio.Lock to prevent race conditions when multiple tasks await the same ReAwaitable instance concurrently. The implementation maintains backward compatibility for non-asyncio environments.

Changes made:

  • Added thread-safe locking mechanism to ReAwaitable class to handle concurrent awaits
  • The lock is lazily initialized on first use to maintain compatibility with non-asyncio environments
  • Added comprehensive tests for concurrent await scenarios
  • Updated documentation to clarify the thread-safe behavior

Why this change is needed:

Previously, when multiple async tasks awaited the same ReAwaitable instance simultaneously, race conditions could occur leading to the underlying coroutine being executed multiple times. This fix ensures that only one task executes the coroutine while others wait and receive the cached result.

Checklist

  • I have double checked that there are no unrelated changes in this pull request
  • I have created at least one test case for the changes I have made
  • I have updated the documentation for the changes I have made
  • I have added my changes to the CHANGELOG.md

Related issues


🙏 Please, if you or your company finds dry-python valuable, help us sustain the project by sponsoring it transparently on https://github.com/sponsors/dry-python. As a thank you, your profile/company logo will be added to our main README which receives hundreds of unique visitors per day.

@AdrianAcala AdrianAcala force-pushed the issue-2108 branch 3 times, most recently from d9321b9 to 7086610 Compare May 30, 2025 19:25
@AdrianAcala AdrianAcala marked this pull request as draft May 30, 2025 19:30
@AdrianAcala
Copy link
Author

Sorry. Working on some missing tests.

@AdrianAcala AdrianAcala marked this pull request as ready for review May 30, 2025 20:44
@AdrianAcala
Copy link
Author

This is good to go.

@AdrianAcala AdrianAcala force-pushed the issue-2108 branch 2 times, most recently from 3bb27ec to f65832f Compare May 31, 2025 01:23
@AdrianAcala
Copy link
Author

I pray this passes.

@AdrianAcala
Copy link
Author

I used act to run the GitHub actions locally and found there was a bit more errors that I had to fix. I really hope this passes now.

Copy link

codecov bot commented May 31, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (82ef3ef) to head (8cb3088).
Report is 338 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##            master     #2150    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files           80        81     +1     
  Lines         2485      2586   +101     
  Branches       437        45   -392     
==========================================
+ Hits          2485      2586   +101     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AdrianAcala AdrianAcala force-pushed the issue-2108 branch 2 times, most recently from 21a4b58 to 8cb3088 Compare May 31, 2025 20:13
…rage

This commit resolves the race condition in concurrent await scenarios and
adds comprehensive multi-framework async support with enhanced test coverage.

## Key Changes:

**ReAwaitable Enhancements:**
- Resolve race condition in concurrent await scenarios by properly handling asyncio locks and coroutine state management
- Add full support for trio and anyio async frameworks beyond asyncio
- Implement intelligent framework detection with graceful fallbacks (asyncio → trio → anyio → threading)
- Add comprehensive DEBUG-level logging for lock fallback scenarios to aid troubleshooting
- Achieve thread-safe concurrent await support across all major Python async frameworks
- Refactor implementation to reduce complexity and improve maintainability

**Test Infrastructure:**
- Achieve 100% branch coverage with comprehensive test cases
- Add extensive tests for all framework scenarios and edge cases
- Add comprehensive tests for logging functionality across all framework scenarios
- Refactor tests into focused helper functions for better maintainability
- Add safe private attribute access helpers to improve test reliability
- Enable pytest-asyncio auto mode for better test infrastructure

**CI/Build Improvements:**
- Update CI workflow to use correct Poetry installation path (.local/bin)
- Fix mypy plugin compatibility and test infrastructure for CI
- Add pytest-asyncio dependency for async test support

**Documentation:**
- Update documentation to reflect enhanced framework compatibility
- Add detailed docstring documenting framework precedence order
- Add changelog entry for the bug fix

This addresses issue dry-python#2108 where trio/anyio users experienced
"coroutine is being awaited already" errors with concurrent awaits.
The implementation now provides thread-safe concurrent await support
across all major Python async frameworks.
@AdrianAcala
Copy link
Author

I added one more improvement so that it supports multiple async frameworks including asyncio, trio, and anyio, with automatic framework detection and fallback support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

ReAwaitable does not support concurrent await call
1 participant
Morty Proxy This is a proxified and sanitized view of the page, visit original site.