Swift Service Lifecycle

Swift Service Lifecycle 提供了一种基本的机制,用于干净地启动和关闭应用程序,在退出之前释放资源。它还提供了一个基于 Signal 的关闭钩子,以便在接收到 TERMINT 等信号时关闭。

Swift Service Lifecycle 的设计理念是,每个应用程序都有一些启动和关闭的工作流逻辑,这些逻辑通常对故障很敏感且难以正确实现。该库以一种安全且可重用的方式编码这种常见需求,且与框架无关,并被设计为可以与任何服务器框架或直接在应用程序中集成。此外,它还与结构化并发原生集成。

这是一个社区驱动的开源项目的开始,积极寻求贡献,无论是代码、文档还是想法。Swift Service Lifecycle 目前提供的功能在API 文档中有所介绍,但它将继续随着社区的投入而发展。

开始使用

如果您有一个服务器端 Swift 应用程序或一个跨平台(例如 Linux、macOS)应用程序,并且您想管理其启动和关闭生命周期,那么 Swift Service Lifecycle 是一个不错的选择。下面您将找到开始使用所需的一切。

添加依赖项

要添加对该软件包的依赖项,请在您的 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:5.9
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。作为库或应用程序开发人员,您应该将您的长期运行的工作建模为实现 Service 协议的服务。该协议仅需要实现一个 func run() async throws 方法。之后,在您的应用程序中,您可以使用 ServiceGroup 来协调多个服务。该组将为每个服务生成一个子任务,并在子任务中调用相应的 run 方法。此外,该组将为配置的信号设置信号监听器,并在每个服务上触发优雅关闭。

import ServiceLifecycle
import Logging

actor 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