Skip to content
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

fix: race condition when initializing multiprocessing manager #26

Merged
merged 5 commits into from
Dec 5, 2023

Conversation

WinPlay02
Copy link
Contributor

@WinPlay02 WinPlay02 commented Dec 4, 2023

Closes #18

Summary of Changes

  • use spawn instead of fork to not deadlock when running tests

Copy link

codecov bot commented Dec 4, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (20e9aac) 100.00% compared to head (6b2d987) 100.00%.

Additional details and impacted files
@@            Coverage Diff            @@
##              main       #26   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            9         9           
  Lines          334       337    +3     
=========================================
+ Hits           334       337    +3     

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

Copy link

github-actions bot commented Dec 4, 2023

🦙 MegaLinter status: ✅ SUCCESS

Descriptor Linter Files Fixed Errors Elapsed time
✅ PYTHON black 3 0 0 0.56s
✅ PYTHON mypy 3 0 1.62s
✅ PYTHON ruff 3 0 0 0.02s
✅ REPOSITORY git_diff yes no 0.02s

See detailed report in MegaLinter reports
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

MegaLinter is graciously provided by OX Security

@lars-reimann
Copy link
Member

lars-reimann commented Dec 4, 2023

The process seems to get stuck inside wait_for_messages when running the test test_should_execute_pipeline_return_valid_placeholder.

@lars-reimann lars-reimann changed the title fix: use spawn instead of fork to maybe not deadlock when running tests test: use spawn instead of fork to maybe not deadlock when running tests Dec 4, 2023
@WinPlay02
Copy link
Contributor Author

WinPlay02 commented Dec 5, 2023

That's true, but this does not seem to be the (main) problem. The main process gets stuck there because it doesn't receive any messages from the pipeline process.

This seems to be related to a race condition when initializing the message queue.
The problem occurred because the fields were changed to cached properties. (https://docs.python.org/3.12/library/functools.html#functools.cached_property)
While cached properties were locked in Python 3.11 to ensure they only get assigned once, they are no longer in Python 3.12.

Note:

Changed in version 3.12: Prior to Python 3.12, cached_property included an undocumented lock to ensure that in multi-threaded usage the getter function was guaranteed to run only once per instance. However, the lock was per-property, not per-instance, which could result in unacceptably high lock contention. In Python 3.12+ this locking is removed.

This caused the multiprocessing manager to sometimes be initialized twice (instead of only once), and the main process would get a different queue than the pipeline process.

Because no messages were sent to the correct queue, the main process waited indefinitely for results.

I confirmed this working under WSL2 with Python 3.12 (or I was incredibly lucky, and no problem has happened since I made the change).

So in the end, there was no deadlock (according to these debugging results), and the fork deprecation message turned out to be a red herring. Although, forking in a threaded program is still bad practice and should be avoided (and is also removed in this PR).

fix: more strict locking during mocking tests
@WinPlay02 WinPlay02 marked this pull request as ready for review December 5, 2023 00:39
@WinPlay02 WinPlay02 requested a review from a team as a code owner December 5, 2023 00:39
@WinPlay02 WinPlay02 changed the title test: use spawn instead of fork to maybe not deadlock when running tests fix: race condition when initializing multiprocessing manager Dec 5, 2023
@WinPlay02
Copy link
Contributor Author

@SmiteDeluxe This should also fix the issue, that the extension sometimes isn't notified of the current pipeline execution progress

Copy link
Member

@lars-reimann lars-reimann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can no longer reproduce #18. Thanks for the fix.

@lars-reimann lars-reimann merged commit fc5934f into main Dec 5, 2023
10 checks passed
@lars-reimann lars-reimann deleted the python-3.12-linux-deadlock branch December 5, 2023 10:33
lars-reimann pushed a commit that referenced this pull request Dec 5, 2023
## [0.4.0](v0.3.0...v0.4.0) (2023-12-05)

### Features

* shutdown messages ([#25](#25)) ([93fcb85](93fcb85)), closes [#24](#24)

### Bug Fixes

* race condition when initializing multiprocessing manager ([#26](#26)) ([fc5934f](fc5934f)), closes [#18](#18)
@lars-reimann
Copy link
Member

🎉 This PR is included in version 0.4.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@lars-reimann lars-reimann added the released Included in a release label Dec 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
released Included in a release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Possible deadlock while running tests
3 participants