Skip to content

[WIP] First pass at some documentation for AsyncChannel #91

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 3 commits into from
Mar 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Sources/AsyncAlgorithms/AsyncChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@
//
//===----------------------------------------------------------------------===//

/// A channel for sending elements from on task to another with back pressure.
///
/// The `AsyncChannel` class is intended to be used as a communication type between tasks,
/// particularly when one task produces values and another task consumes those values. The back
/// pressure applied by `send(_:)` and `finish()` via the suspension/resume ensure that
/// the production of values does not exceed the consumption of values from iteration. Each of these
/// methods suspends after enqueuing the event and is resumed when the next call to `next()`
/// on the `Iterator` is made.
public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
/// The iterator for a `AsyncChannel` instance.
public struct Iterator: AsyncIteratorProtocol, Sendable {
let channel: AsyncChannel<Element>
var active: Bool = true
Expand All @@ -18,6 +27,7 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
self.channel = channel
}

/// Await the next sent element or finish.
public mutating func next() async -> Element? {
guard active else {
return nil
Expand Down Expand Up @@ -98,6 +108,7 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {

let state = ManagedCriticalState(State())

/// Create a new `AsyncChannel` given an element type.
public init(element elementType: Element.Type = Element.self) { }

func establish() -> Int {
Expand Down Expand Up @@ -180,14 +191,19 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
continuation?.resume(with: result)
}

/// Send an element to an awaiting iteration. This function will resume when the next call to `next()` is made.
/// If the channel is already finished then this returns immediately
public func send(_ element: Element) async {
await _send(.success(element))
}

/// Send a finish to an awaiting iteration. This function will resume when the next call to `next()` is made.
/// If the channel is already finished then this returns immediately
public func finish() async {
await _send(.success(nil))
}

/// Create an `Iterator` for iteration of an `AsyncChannel`
public func makeAsyncIterator() -> Iterator {
return Iterator(self)
}
Expand Down
3 changes: 3 additions & 0 deletions Sources/AsyncAlgorithms/AsyncThrowingChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
//
//===----------------------------------------------------------------------===//

/// A throwing channel for sending elements from on task to another with back pressure.
///
/// The `AsyncThrowingChannel` class is intended to be used as a communication types between tasks., particularly when one task produces values and another task consumes those values. The back pressure applied by `send(_:)`, `fail(_:)` and `finish()` via the suspension/resume ensure that the production of values does not exceed the consumption of values from iteration. Each of these methods suspends after enqueuing the event and is resumed when the next call to `next()` on the `Iterator` is made.
public final class AsyncThrowingChannel<Element: Sendable, Failure: Error>: AsyncSequence, Sendable {
public struct Iterator: AsyncIteratorProtocol, Sendable {
let channel: AsyncThrowingChannel<Element, Failure>
Expand Down