Swift 服务生命周期提供了一种基本的机制来干净地启动和关闭应用程序,在退出前按顺序释放资源。它还提供了一个基于 Signal
的关闭钩子,以便在收到 TERM
或 INT
等信号时关闭。
Swift 服务生命周期的设计理念是,每个应用程序都有一些启动和关闭的工作流式逻辑,这些逻辑通常对故障很敏感且难以正确实现。该库以安全且可重用的方式编码了这种常见的需求,它不特定于框架,并且旨在与任何服务器框架或直接在应用程序中集成。此外,它还与结构化并发原生集成。
这是一个社区驱动的开源项目的开始,积极寻求贡献,无论是代码、文档还是想法。Swift 服务生命周期目前提供的功能在API 文档中涵盖,但它将继续随着社区的投入而发展。
如果您有一个服务器端 Swift 应用程序或一个跨平台(例如,Linux、macOS)应用程序,并且您想要管理其启动和关闭生命周期,则应使用 Swift 服务生命周期。下面您将找到开始入门所需了解的一切。
要在包中添加依赖项,请在您的 Package.swift
中声明它
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.0.0"),
并将 ServiceLifecycle
添加到您的应用程序目标的依赖项中
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle")
带有 ServiceLifecycle
作为依赖项的 Package.swift
文件示例
// swift-tools-version:6.0
import PackageDescription
let package = Package(
name: "my-application",
dependencies: [
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.3.0"),
],
targets: [
.target(name: "MyApplication", dependencies: [
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle")
]),
.testTarget(name: "MyApplicationTests", dependencies: [
.target(name: "MyApplication"),
]),
]
)
您可以在下面找到一个简短的用法示例。您可以在此处找到有关如何使用 ServiceLifecycle 的更详细文档。
ServiceLifecycle 由两个主要的构建块组成。Service
协议和 ServiceGroup
actor。作为库或应用程序开发人员,您应该将您的长期运行工作建模为实现 Service
协议的服务。该协议仅要求实现一个 func run() async throws
方法。一旦实现,您的应用程序就可以使用 ServiceGroup
来编排多个服务。该组将为每个服务生成一个子任务,并在子任务中调用相应的 run
方法。此外,该组将为配置的信号设置信号监听器,并在每个服务上触发优雅关闭。
import ServiceLifecycle
import Logging
// A service can be implemented by a struct, class or actor. For this example we are using a struct.
struct FooService: Service {
func run() async throws {
print("FooService starting")
try await Task.sleep(for: .seconds(10))
print("FooService done")
}
}
@main
struct Application {
static let logger = Logger(label: "Application")
static func main() async throws {
let service1 = FooService()
let service2 = FooService()
let serviceGroup = ServiceGroup(
services: [service1, service2],
gracefulShutdownSignals: [.sigterm],
logger: logger
)
try await serviceGroup.run()
}
}
有关安全流程的详细信息,请参阅SECURITY.md。