Skip to content

[Concurrency] YieldingContinuation #36730

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

Merged
merged 11 commits into from
Apr 8, 2021

Conversation

phausler
Copy link
Contributor

@phausler phausler commented Apr 2, 2021

This implements a YieldingContinuation type suitable for emitting values more than once via a yielding family of functions and awaiting production via next

This is a type suitable for usage points that need to resume an awaiting function more than once. This can be used to implement AsyncIteratorProtocol adopters for AsyncSequence that are sourced from state that is external from the control of the iterator. Callbacks or delegation can be passed this continuation type (unlike the Unsafe and Checked variants usable for singular callbacks) as an escaping/sendable concept. This means that the continuation can escape into closures that get called more than once. Yielding will return a boolean state identifying that the continuation was resumed or not. Ignoring this will result in a dropping style behavior (e.g. if no one is awaiting a value the value will be dropped). Implementors of async iterators need to choose if the values are distinct and need to be buffered for use before the next awaiting call is invoked.

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please smoke test macOS

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please test

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please smoke test macOS

3 similar comments
@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please smoke test macOS

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please smoke test macOS

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please smoke test macOS

@swift-ci
Copy link
Contributor

swift-ci commented Apr 3, 2021

Build failed
Swift Test OS X Platform
Git Sha - 262ae2771c60d0cc7188320e1dfd479dd1c92517

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please smoke test macOS

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please clean smoke test macOS

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please test macOS

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please smoke test macOS

@swift-ci
Copy link
Contributor

swift-ci commented Apr 3, 2021

Build failed
Swift Test OS X Platform
Git Sha - 262ae2771c60d0cc7188320e1dfd479dd1c92517

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please smoke test macOS

@phausler
Copy link
Contributor Author

phausler commented Apr 3, 2021

@swift-ci please test macOS

@swift-ci
Copy link
Contributor

swift-ci commented Apr 4, 2021

Build failed
Swift Test OS X Platform
Git Sha - 262ae2771c60d0cc7188320e1dfd479dd1c92517

@phausler
Copy link
Contributor Author

phausler commented Apr 4, 2021

@swift-ci please smoke test macOS

@phausler
Copy link
Contributor Author

phausler commented Apr 5, 2021

@swift-ci please test macOS

@swift-ci
Copy link
Contributor

swift-ci commented Apr 5, 2021

Build failed
Swift Test OS X Platform
Git Sha - 262ae2771c60d0cc7188320e1dfd479dd1c92517

@phausler
Copy link
Contributor Author

phausler commented Apr 5, 2021

@swift-ci please smoke test

@phausler phausler force-pushed the phausler/yielding_continuation_2 branch from 3fdab27 to 46ff414 Compare April 5, 2021 15:07
@phausler
Copy link
Contributor Author

phausler commented Apr 5, 2021

@swift-ci please smoke test

Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

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

Mostly LGTM. I'll leave the naming question to Evolution.

@usableFromInline
internal final class Storage: UnsafeSendable {
@usableFromInline
var continuation: UnsafeContinuation<Element, Error>?
Copy link
Contributor

Choose a reason for hiding this comment

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

You could reduce metadata explosion by hoisting this effectively nongeneric storage class out of the generic outer type, so we only need one class object for all instances.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm good idea; and then store the continuation as a raw crunchy continuation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

extracted!

/// Await a resume from a call to a yielding function.
///
/// - Return: The element that was yielded or a error that was thrown.
public func next() async throws -> Element {
Copy link
Contributor

Choose a reason for hiding this comment

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

The signature of next() here is wrong for any Failure type other than Error, so it might be least-bad to move this into an extension where Failure == Error, to leave room for a generic throws T API here if we ever get typed throws.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that poses a problem; then it is invalid to construct ones w/ a specific error type - should we enforce that initializer into that extension as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

converted to the specific variant.

…o acqrel atomics, and change the error type to be enforced to Error existentials for next.
@phausler
Copy link
Contributor Author

phausler commented Apr 5, 2021

@swift-ci please smoke test

@phausler
Copy link
Contributor Author

phausler commented Apr 6, 2021

@swift-ci please smoke test macOS

let failure2 = SomeError()
let t = detach {
do {
let value1 = try await continuation.next()
Copy link
Member

Choose a reason for hiding this comment

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

We should have an expectUnreachable after this line (and below, in this test and 2x in the next test)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fair, will change

@natecook1000
Copy link
Member

@swift-ci Please build toolchain macOS platform

@phausler
Copy link
Contributor Author

phausler commented Apr 7, 2021

@swift-ci please smoke test

Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

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

Okay, my non-evolution concerns have been addressed

@phausler
Copy link
Contributor Author

phausler commented Apr 8, 2021

@swift-ci please smoke test linux

@phausler phausler merged commit eb0bd6a into swiftlang:main Apr 8, 2021
drodriguez added a commit to drodriguez/swift that referenced this pull request Apr 9, 2021
After the merge of swiftlang#36730, both VS2017 and VS2019 CI machines started
failing. There are many crashes related to concurrency. Disable the
tests in Windows to not loose signal on the CI machines.

See https://bugs.swift.org/browse/SR-14333 for more disabled tests and
discussion.
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.

6 participants