-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Overhaul service lifecycle for Structured Concurrency
# Motivation Since the release of Swift Concurrency the server ecosystem has adopted `async`/`await` in a lot of APIs making the user experience amazing. Another thing that Swift Concurrency introduced is Structured Concurrency which allows to create a task tree that with parent to child relations. Structured Concurrency has many benefits such as automatic cancellation and task local propagation. The current state of this library predates the introduction of Swift Concurrency and is not inline anymore with how applications are structured that want to leverage Concurrency. # Modification This PR overhauls the implementation of service lifecycle completely. The reason for this is that the current implementation is very focused on how NIO based applications work before the introduction of Concurrency. Furthermore, Structured Concurrency is actually replacing part of the current functionality by providing new scoping mechanisms. The overhauled implementation provides two primitive types. Anew `Service` protocol and a `ServiceRunner`. The former is providing a clear API which services have to conform to so that they can be run by the `ServiceRunner`. An example usage of the types looks like this ```swift actor FooService: Service { func run() async throws {} func shutdownGracefully() async throws {} } actor BarService: Service { func run() async throws {} func shutdownGracefully() async throws {} } let fooService = FooService() let barService = BarService() let runner = ServiceRunner( services: [fooService, barService], configuration: .init(), logger: logger ) try await runner.run() ``` # Result We now have a service lifecycle library that integrates nicely with Structured Concurrency. Its value add is that it solves to complex setup of the task group with the signal handling. Furthermore, it provides a currency type `Service` that can be passed to inject services.
- Loading branch information
1 parent
fbdb075
commit 695cde5
Showing
38 changed files
with
1,665 additions
and
4,750 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
version: 1 | ||
builder: | ||
configs: | ||
- documentation_targets: [Lifecycle, LifecycleNIOCompat] | ||
- documentation_targets: [ServiceLifecycle, UnixSignals] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,23 @@ | ||
# file options | ||
|
||
--swiftversion 5.0 | ||
--swiftversion 5.5 | ||
--exclude .build | ||
|
||
# format options | ||
|
||
--self insert | ||
--patternlet inline | ||
--ranges nospace | ||
--stripunusedargs unnamed-only | ||
--ifdef no-indent | ||
--extensionacl on-declarations | ||
--disable typeSugar # https://github.com/nicklockwood/SwiftFormat/issues/636 | ||
--disable andOperator | ||
--disable wrapMultilineStatementBraces | ||
--disable enumNamespaces | ||
--disable redundantExtensionACL | ||
--disable redundantReturn | ||
--disable preferKeyPath | ||
--disable sortedSwitchCases | ||
|
||
# rules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,60 @@ | ||
// swift-tools-version:5.6 | ||
// swift-tools-version:5.7 | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "swift-service-lifecycle", | ||
platforms: [ | ||
.macOS(.v10_15), | ||
.iOS(.v13), | ||
.watchOS(.v6), | ||
.tvOS(.v13), | ||
], | ||
products: [ | ||
.library(name: "Lifecycle", targets: ["Lifecycle"]), | ||
.library(name: "LifecycleNIOCompat", targets: ["LifecycleNIOCompat"]), | ||
.library( | ||
name: "ServiceLifecycle", | ||
targets: ["ServiceLifecycle"] | ||
), | ||
.library( | ||
name: "UnixSignals", | ||
targets: ["UnixSignals"] | ||
), | ||
], | ||
dependencies: [ | ||
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.0"), | ||
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"), | ||
.package(url: "https://github.com/apple/swift-metrics.git", "1.0.0" ..< "3.0.0"), | ||
.package(url: "https://github.com/swift-server/swift-backtrace.git", from: "1.1.1"), | ||
.package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0"), // used in tests | ||
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), | ||
.package( | ||
url: "https://github.com/apple/swift-log.git", | ||
from: "1.5.2" | ||
), | ||
.package( | ||
url: "https://github.com/apple/swift-docc-plugin", | ||
from: "1.0.0" | ||
), | ||
], | ||
targets: [ | ||
.target(name: "Lifecycle", dependencies: [ | ||
.product(name: "Atomics", package: "swift-atomics"), | ||
.product(name: "Logging", package: "swift-log"), | ||
.product(name: "Metrics", package: "swift-metrics"), | ||
.product(name: "Backtrace", package: "swift-backtrace"), | ||
]), | ||
|
||
.target(name: "LifecycleNIOCompat", dependencies: [ | ||
"Lifecycle", | ||
.product(name: "NIO", package: "swift-nio"), | ||
]), | ||
|
||
.testTarget(name: "LifecycleTests", dependencies: ["Lifecycle", "LifecycleNIOCompat"]), | ||
.target( | ||
name: "ServiceLifecycle", | ||
dependencies: [ | ||
.product( | ||
name: "Logging", | ||
package: "swift-log" | ||
), | ||
.target(name: "UnixSignals"), | ||
] | ||
), | ||
.target( | ||
name: "UnixSignals" | ||
), | ||
.testTarget( | ||
name: "ServiceLifecycleTests", | ||
dependencies: [ | ||
.target(name: "ServiceLifecycle"), | ||
] | ||
), | ||
.testTarget( | ||
name: "UnixSignalsTests", | ||
dependencies: [ | ||
.target(name: "UnixSignals"), | ||
] | ||
), | ||
] | ||
) |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.