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

[release/8.0] Fix cancellation unregistration in DataflowBlock.OutputAvailableAsync #102376

Merged
merged 2 commits into from
May 29, 2024

Conversation

stephentoub
Copy link
Member

OutputAvailableAsync is not unregistering from the supplied CancellationToken. If a cancelable token is supplied and is long lived, each call with that token to OutputAvailableAsync will add another callback into that token, and that will continue to grow until either the token is dropped or has been cancellation requested. For a long-lived cancellation token, this is akin to a leak.

The implementation was trying to be too clever in avoiding an additional continuation that was previously there. However, this continuation makes it a lot easier to avoid possible deadlocks that can occur if a cancellation request comes in concurrently with a message being pushed. Instead of trying to avoid it, just use an async method, which still incurs the extra task but does so with less allocation and greatly simplifies the code while also fixing the issue, as all cleanup can now be done in the continuation as part of the async method.

Backport of #99632

Customer Impact

Unbounded memory growth if a long-lived CancellationToken is used with OutputAvailableAsync; each call would end up rooting a small object into the token.

Testing

Normal CI testing, plus local stress testing to show that the leak no longer exists.

Risk

Low

…dotnet#99632)

OutputAvailableAsync is not unregistering from the supplied CancellationToken. If a cancelable token is supplied and is long lived, each call with that token to OutputAvailableAsync will add another callback into that token, and that will continue to grow until either the token is dropped or has been cancellation requested.  For a long-lived cancellation token, this is akin to a leak.

The implementation was trying to be too clever in avoiding an additional continuation that was previously there. However, this continuation makes it a lot easier to avoid possible deadlocks that can occur if a cancellation request comes in concurrently with a message being pushed.  Instead of trying to avoid it, just use an async method, which still incurs the extra task but does so with less allocation and greatly simplifies the code while also fixing the issue, as all cleanup can now be done in the continuation as part of the async method.
@stephentoub stephentoub added the Servicing-consider Issue for next servicing release review label May 17, 2024
@stephentoub stephentoub added this to the 8.0.x milestone May 17, 2024
Copy link
Contributor

Tagging subscribers to this area: @mangod9
See info in area-owners.md if you want to be subscribed.

@ericstj ericstj added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels May 22, 2024
@ericstj
Copy link
Member

ericstj commented May 22, 2024

Approved in mail.

@ericstj
Copy link
Member

ericstj commented May 22, 2024

Needs package authoring.

Copy link
Member

@ericstj ericstj left a comment

Choose a reason for hiding this comment

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

LGTM

@stephentoub
Copy link
Member Author

Thanks for taking care of the package authoring, @ericstj.

@stephentoub stephentoub merged commit 48a9496 into dotnet:release/8.0-staging May 29, 2024
109 checks passed
@stephentoub stephentoub deleted the backport99632 branch May 29, 2024 01:41
@github-actions github-actions bot locked and limited conversation to collaborators Jun 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Threading Servicing-approved Approved for servicing release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants