IdentifiableContinuation

0.1.0

Swift continuation that conforms to Identifiable and includes a cancellation handler.
swhitty/IdentifiableContinuation

What's New

Actor Isolation

2024-03-11T06:21:14Z

Adds explicit actor isolation to ensure the closure is executed within the actors isolation:

let val: String = await withIdentifiableContinuation(isolation: self) { 
    $0.resume(returning: "bar")
}

This allows actors to synchronously start continuations and mutate their isolated state before suspension occurs. The onCancel: handler is @Sendable and can be called at any time after the body has completed. Manually check Task.isCancelled before creating the continuation to prevent performing unrequired work.

let val: String = await withIdentifiableContinuation(isolation: self) {
  // executed within actor isolation so can immediatley mutate actor state
  continuations[$0.id] = $0
} onCancel: { id in
  // @Sendable closure executed outside of actor isolation requires `await` to mutate actor state
  Task { await self.cancelContinuation(with: id) }
}

Previous versions used async closures and unstructured tasks to work with actors but SE-0420 Inheritance of Actor isolation includes the new #isolation keyword that will allow isolation: self to be automatically filled in by the compiler.

Build Codecov Platforms Swift 5.10 License Twitter

Introduction

IdentifiableContinuation is a lightweight wrapper around CheckedContinuation that conforms to Identifiable and includes an easy to use cancellation handler with the id.

Installation

IdentifiableContinuation can be installed by using Swift Package Manager.

Note: IdentifiableContinuation requires Swift 5.7 on Xcode 14+. It runs on iOS 13+, tvOS 13+, macOS 10.15+, Linux and Windows. To install using Swift Package Manager, add this to the dependencies: section in your Package.swift file:

.package(url: "https://github.com/swhitty/IdentifiableContinuation.git", .upToNextMajor(from: "0.1.0"))

Usage

Usage is similar to existing continuations, but requires an Actor to ensure the closure is executed within the actors isolation:

let val: String = await withIdentifiableContinuation(isolation: self) { 
    $0.resume(returning: "bar")
}

This allows actors to synchronously start continuations and mutate their isolated state before suspension occurs. The onCancel: handler is @Sendable and can be called at any time after the body has completed. Manually check Task.isCancelled before creating the continuation to prevent performing unrequired work.

let val: String = await withIdentifiableContinuation(isolation: self) {
  // executed within actor isolation so can immediatley mutate actor state
  continuations[$0.id] = $0
} onCancel: { id in
  // @Sendable closure executed outside of actor isolation requires `await` to mutate actor state
  Task { await self.cancelContinuation(with: id) }
}

Credits

IdentifiableContinuation is primarily the work of Simon Whitty.

(Full list of contributors)

Description

  • Swift Tools 5.8.0
View More Packages from this Author

Dependencies

  • None
Last updated: Fri Mar 22 2024 07:51:23 GMT-0900 (Hawaii-Aleutian Daylight Time)