Swift 服务生命周期

Swift 服务生命周期提供了一种基本的机制来干净地启动和关闭应用程序,在退出前按顺序释放资源。它还提供了一个基于 Signal 的关闭钩子,以便在收到 TERMINT 等信号时关闭。

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 的更详细文档。

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