Skip to content

Instantly share code, notes, and snippets.

@samsonjs
Last active April 28, 2025 17:11
Show Gist options
  • Save samsonjs/47828af8359ee35af4a6c2011f0994d7 to your computer and use it in GitHub Desktop.
Save samsonjs/47828af8359ee35af4a6c2011f0994d7 to your computer and use it in GitHub Desktop.
Cool exploration but it doesn't work unless everything is sendable, and AsyncSequence and AsyncStream don't seem to be sendable
// UPDATE: See https://github.com/samsonjs/AsyncMonitor if this is your kind of thing!
import Foundation
public final class AsyncMonitorTask: Hashable {
let task: Task<Void, Never>
init<Element: Sendable>(
sequence: sending any AsyncSequence<Element, Never>,
performing block: @escaping @MainActor (Element) async -> Void
) {
self.task = Task {
for await element in sequence {
await block(element)
}
}
}
deinit {
task.cancel()
}
public func store(in set: inout Set<AsyncMonitorTask>) {
set.insert(self)
}
}
// MARK: - Hashable conformance
public extension AsyncMonitorTask {
static func == (lhs: AsyncMonitorTask, rhs: AsyncMonitorTask) -> Bool {
lhs.task == rhs.task
}
func hash(into hasher: inout Hasher) {
hasher.combine(task)
}
}
public extension AsyncSequence where Element: Sendable, Failure == Never {
func monitor(_ block: @escaping @Sendable (Element) async -> Void) -> AsyncMonitorTask {
AsyncMonitorTask(sequence: self, performing: block)
}
func monitor<Context: AnyObject & Sendable>(
context: Context,
_ block: @escaping @Sendable (Context, Element) async -> Void
) -> AsyncMonitorTask {
AsyncMonitorTask(sequence: self) { [weak context] element in
guard let context else { return }
await block(context, element)
}
}
}
@samsonjs
Copy link
Author

This looks pretty much perfect! Thanks for teaching me about the isolation capture trick too, I didn't know about that one. Losing MainActor-ness here is perfect really, I think it should inherit the caller's isolation and stay there, unlike where this was extracted/expanded from.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment