-
Notifications
You must be signed in to change notification settings - Fork 73
BREAKING: Converts to Swift Concurrency #166
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
base: main
Are you sure you want to change the base?
BREAKING: Converts to Swift Concurrency #166
Conversation
.package(url: "https://github.com/apple/swift-collections", .upToNextMajor(from: "1.0.0")), | ||
], | ||
targets: [ | ||
.target( | ||
name: "GraphQL", | ||
dependencies: [ | ||
.product(name: "NIO", package: "swift-nio"), | ||
.product(name: "OrderedCollections", package: "swift-collections"), | ||
] | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe enable strict concurrency as well
swiftLanguageVersions: [.v5, .version("6")]
let fieldASTs = field.value | ||
let fieldPath = path.appending(field.key) | ||
// TODO: Probably need to lock around results access here. | ||
results[field.key] = try await resolveField( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is going to cause issues. Best way to do this is have the child task return an index and result and fill out the ordered dictionary when parsing the results of the group.
group.addTask {
...
return (key: field.key, result: try await resolveField(...))
}
for try await result in group {
results[result.key] = result.result
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah perfect, thanks for the insight on how best to do this. I've adjusted to this approach.
|
||
completedResults.append(completedItem) | ||
// TODO: Probably need to block around completedResults access here | ||
completedResults[index] = completedItem |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment above, about returning index with result to group
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed this also
@@ -3,7 +3,7 @@ open class EventStream<Element> { | |||
public init() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated to concurrency, but should this not be a protocol
@@ -30,13 +30,13 @@ public class ConcurrentEventStream<Element>: EventStream<Element> { | |||
|
|||
@available(macOS 10.15, iOS 15, watchOS 8, tvOS 15, *) | |||
extension AsyncThrowingStream { | |||
func mapStream<To>(_ closure: @escaping (Element) throws -> To) | |||
func mapStream<To>(_ closure: @escaping (Element) async throws -> To) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason you have this when AsyncSequence.map exists?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unstructured Tasks aren't great. They make cancellation hard.
In actual fact you could just replace the whole of this file with AsyncStream<Element>
. This opens up all the functions that AsyncSequence has eg map, filter, compactMap, first, etc and cancellation will come for free.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had created this a few years ago before Swift Concurrency existed to abstract different AsyncSequence/PubSub backends (at the time, options included RxSwift and Combine). Since we're switching over to concurrency, I agree, we should switch to having AsyncThrowingStream as a first class member in our API. I've done that work here: 9ec313a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess @adam-fowler’s point is to use some async sequence in the public APIs instead of the concrete stream, is that correct @adam-fowler ?
b6afc7d
to
cd2009d
Compare
This removes the NIO dependency. It is breaking because it removes all Swift NIO-isms that were present in the public APIs (like EventLoopFuture and EventLoopGroup argument/return types).
cd2009d
to
cf9f195
Compare
cf9f195
to
ac8c049
Compare
ac8c049
to
9ec313a
Compare
The intent is to replace it with swift-distributed-tracing integration.
This resolves the race condition caused by the inbox counts and the event delivery. If event delivery happens before the subsequent publish increments the inbox counts, then the counts will be lower than expected. Resolved by just not asking for inbox counts, since they aren't relevant to the test.
6a3bb81
to
1bc642c
Compare
This removes the NIO dependency. It is breaking because it removes all Swift NIO-isms that were present in the public APIs (like EventLoopFuture and EventLoopGroup argument/return types).