Skip to content

effects with cancel scopes #1090

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

Closed
wants to merge 1 commit into from

Conversation

rmorshea
Copy link
Collaborator

@rmorshea rmorshea commented Jul 4, 2023

By submitting this pull request you agree that all contributions to this project are made under the MIT license.

Issues

Closes: #956

Presently, there is no way for async effects to shield themselves from cancellation. This is a problem if an effect needs to perform some cleanup before exiting or if the effect is performing an operation that, if it were to stop halfway through, would leave the program in an invalid state.

Summary

Leverage anyio.CancelScopeto allow users to shield important operations from cancellation. Cancellation shielding can be achieved by entering aCancelScope(shield=True)` async context:

@use_effect
async def my_critical_effect():
    await non_critical_task()

    async with CancelScope(shield=True):
        await critical_task()

    await another_non_critical_task()

In the code above, if the effect reaches the critical_task(), it will always complete that before exiting, even if the effect has been cancelled by an unmounting component.

The current implementation is not perfect though. We ought to block until all effects associated with the current component have exited. This will require asyncifying some of the underlying rendering logic in Layout. This isn't too much work, but it can be left for a follow up PR. In its current state, if a user shielded an effect from cancellation it is technically possible for the lifetime of the cancelled (but currently shielded) effect from overlapping with the lifetime of the effect initiated as part of the next render.

Checklist

  • Tests have been included for all bug fixes or added functionality.
  • The changelog.rst has been updated with any significant changes.

@rmorshea rmorshea marked this pull request as draft July 4, 2023 23:18
@rmorshea rmorshea mentioned this pull request Jul 4, 2023
2 tasks
@Archmonger
Copy link
Contributor

I think a prevent_cancel = ... parameter in use_effect might be a convenient way of handling this.

@rmorshea rmorshea closed this Jul 7, 2023
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.

Better Async Effect Cleanup
2 participants