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

_NIOConcurrency: Rename completeWithAsync(_:) to completeWithTask(_:) and return task #1911

Merged
merged 6 commits into from
Aug 3, 2021

Conversation

simonjbeaumont
Copy link
Contributor

Return Task from EventLoopPromise.completeWithAsync(_:) wrapper.

Motivation:

Bridging an async function into NIO is done by calling completeWithAsync(_ body:) on an EventLoopPromise. This spins up a Task and awaits the result of the async closure that was passed in and uses the result to fulfil the promise with the value of the function, if it was successful, or with the error, if the function threw.

In some cases we may want to cancel this operation from the outside.

Modifications:

This patch adds a discardable return value to EventLoopPromise.completeWithAsync(_:) which is the Task it creates.

Result:

Users of EventLoopPromise.completeWithAsync(_:) are now able to explicitly cancel the Task that is being used to fulfil the promise.

@simonjbeaumont
Copy link
Contributor Author

//cc @glbrntt

Signed-off-by: Si Beaumont <beaumont@apple.com>
@glbrntt glbrntt requested a review from Lukasa July 23, 2021 09:27
@glbrntt glbrntt added the semver/none No version bump required. label Jul 23, 2021
@glbrntt
Copy link
Contributor

glbrntt commented Jul 23, 2021

Soundness should be fixed by #1913

Copy link
Contributor

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

Seems reasonable to me.

@weissi
Copy link
Member

weissi commented Jul 26, 2021

@Lukasa doesn't this leak that we do create a new Task? CC @ktoso

@ktoso
Copy link
Member

ktoso commented Jul 26, 2021

If you mean "leaks implementation detail" then kind of yeah, but it does not cause a "leak leak".

Let's think if this leaking of impl detail is actually "impl detail" or "necessary detail"...

There's basically two ways to cancel a task:

    1. the parent is cancelled, and thus we are as well
    1. the task's handle (Task<...>) is cancelled explicitly (a task in a group is similar, group.cancelAll() is the same story), and an async let task getting cancelled because a throw happened is also basically <the task of the async let>.cancel())

In that sense... Since this API is intended to be called from a "probably not async context" (maybe it is a sync function but actually running inside of a Task, but in any case we potentially cannot await in this scope), so we can't really rely on 1), so indeed exposing the Task so that it may be cancelled is the only other option.

Perhaps a different name here would be better though? let task = promise.completeWithTask { <clearly this is a task> } and task.cancel() reads pretty logical, it also explains what the returned value there is, wdyt?

The alternative, without offering such API, is to force people to: let t = Task { promise.completeWithAsync/Task { ... } } which then they might cancel, so I don't think it's worth making the life of developers harder here, might as well just return the task we created.

@Lukasa
Copy link
Contributor

Lukasa commented Jul 26, 2021

I'm with @ktoso: while it absolutely leaks an implementation detail, this is a detail that is unavoidably necessary for participating correctly in structured concurrency.

@Lukasa
Copy link
Contributor

Lukasa commented Jul 26, 2021

I would be open to renaming to completeWithTask though.

@Lukasa
Copy link
Contributor

Lukasa commented Jul 26, 2021

And concretely the reason this change was proposed was for the grpc-swift project, which will want something like this. The fact that they need it suggests that it's likely to be generally useful.

…pleteWithTask(_:)

Signed-off-by: Si Beaumont <beaumont@apple.com>
@simonjbeaumont
Copy link
Contributor Author

Ah... I see I broke the api breakage pipeline. I didn't realise this underscore module was intended to be API stable at this point. Should I leave the original one in (that returns void) and add a completely separate one with a fixit?

@Lukasa
Copy link
Contributor

Lukasa commented Jul 26, 2021

The underscore module is not API stable, but the api breakage script doesn’t know that. We can merge over it.

@simonjbeaumont simonjbeaumont changed the title _NIOConcurrency: Return Task from EventLoopPromise.completeWithAsync(_:) _NIOConcurrency: Rename completeWithAsync(_:) to completeWithTask(_:) and return task Jul 27, 2021
Copy link
Member

@ktoso ktoso left a comment

Choose a reason for hiding this comment

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

and "yay!" for the rename while at it :)

@glbrntt glbrntt merged commit e66b64e into apple:main Aug 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver/none No version bump required.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants