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

raise BrokenResourceError if lock owner has exited. #3080

Closed
wants to merge 1 commit into from

Conversation

jakkdl
Copy link
Member

@jakkdl jakkdl commented Sep 2, 2024

Partially addresses #3035

  • Idk if adding test_lock_multiple_acquire is very meaningful
  • need to add newsfragment

It's possible that a full implementation for #3035 makes this redundant, but this was easy enough to write&test I thought I might as well push it as a PR that improves the status quo for now.

@jakkdl jakkdl requested a review from Zac-HD September 2, 2024 14:36
Copy link

codecov bot commented Sep 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.60%. Comparing base (51b2dff) to head (41a298a).
Report is 68 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3080   +/-   ##
=======================================
  Coverage   99.60%   99.60%           
=======================================
  Files         121      121           
  Lines       17882    17900   +18     
  Branches     3214     3221    +7     
=======================================
+ Hits        17811    17829   +18     
  Misses         50       50           
  Partials       21       21           
Files with missing lines Coverage Δ
src/trio/_sync.py 100.00% <100.00%> (ø)
src/trio/_tests/test_sync.py 100.00% <100.00%> (ø)

Copy link
Contributor

@A5rocks A5rocks left a comment

Choose a reason for hiding this comment

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

Can you add a newsfragment?

See https://github.com/python-trio/trio/issues/3035
"""
lock = trio.Lock()
with pytest.raises(trio.TooSlowError):
Copy link
Contributor

Choose a reason for hiding this comment

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

How about xfailing this test?

and inspect.getcoroutinestate(self._owner.coro) is inspect.CORO_CLOSED
):
raise trio.BrokenResourceError(
"Attempted acquire on Lock which will never be released, owner has exited.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"Attempted acquire on Lock which will never be released, owner has exited.",
"Attempted acquire on Lock which will never be released as the owner has exited.",

I'm not sure this is the ideal message either way but the alternative I can think of isn't great either: "Deadlock detected: acquiring lock which will never be released."

Copy link
Member

@Zac-HD Zac-HD left a comment

Choose a reason for hiding this comment

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

I'm somewhat concerned about the performance impact of inspect.getcoroutinestate in acquire_nowait(), which might be fine.

The larger problem is that it only addresses the case where the holding task is already gone at acquire-time; I think we should probably go directly to the general solution of adding a ParkingLot.mark_resource_broken() method and using that from Lock.

@A5rocks
Copy link
Contributor

A5rocks commented Sep 4, 2024

I'm somewhat concerned about the performance impact of inspect.getcoroutinestate in acquire_nowait(), which might be fine.

Good point, if someone's polling acquire_nowait(). I think inspect.getcoroutinestate is decently fast but yeah having a way to mark a ParkingLot as poisoned/broken would be faster. ... Though if someone's polling acquire_nowait and that doesn't check the owner status, that's weird so maybe not.

The larger problem is that it only addresses the case where the holding task is already gone at acquire-time; I think we should probably go directly to the general solution of adding a ParkingLot.mark_resource_broken() method and using that from Lock.

Yeah, the problem is we can't just add a way to poison a ParkingLot, we also need a way to know when Lock's task gets ended. We can't use a weakref.finalizer because no guarantees on when Task gets deleted (it could be stored somewhere else other than _owner), so I think we need something in trio's event loop itself.

@jakkdl
Copy link
Member Author

jakkdl commented Sep 5, 2024

I'm somewhat concerned about the performance impact of inspect.getcoroutinestate in acquire_nowait(), which might be fine.

I ran a simple benchmark now and could not detect any difference with or without a call to inspect.getcoroutinestate.

The larger problem is that it only addresses the case where the holding task is already gone at acquire-time; I think we should probably go directly to the general solution of adding a ParkingLot.mark_resource_broken() method and using that from Lock.

Yes this PR intentionally only made the easy fix from #3035 (comment), but if the full fix turns out doable then we'll close this one.

@jakkdl
Copy link
Member Author

jakkdl commented Sep 17, 2024

This will probably end up closed in favor of #3081

@A5rocks
Copy link
Contributor

A5rocks commented Oct 9, 2024

Now unnecessary.

@A5rocks A5rocks closed this Oct 9, 2024
@jakkdl jakkdl deleted the multi_task_lock branch October 9, 2024 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants