Swift 服务发现简介
我很高兴地宣布 Swift 服务器生态系统的一个新的开源项目:Swift Service Discovery(Swift 服务发现)。Service Discovery 是一个 Swift 包,旨在建立一个标准 API,可由各种服务发现后端(如基于 DNS、键值存储等)实现。
它是如何工作的?
Swift Service Discovery 包仅定义 API,类似于 SwiftLog 和 SwiftMetrics;实际功能由后端实现提供。
概念
- 服务标识:每个服务都必须具有唯一的标识。
Service
表示后端实现中使用的标识类型。 - 服务实例:一个服务可以有零个或多个实例,每个实例都有一个关联的位置(通常是主机-端口)。
Instance
表示后端实现中使用的服务实例类型。
服务器应用程序
应用程序所有者需要选择一个服务发现后端,以使查询可用。这通过添加对所需后端实现的依赖并在程序开始时实例化它来完成。
例如,假设选择假设的 DNSBasedServiceDiscovery
作为后端
// 1) Import the service discovery backend package
import DNSBasedServiceDiscovery
// 2) Create a concrete ServiceDiscovery object
let serviceDiscovery = DNSBasedServiceDiscovery()
要获取当前的实例列表(其中 result
是 Result<[Instance], Error>
)
serviceDiscovery.lookup(service) { result in
...
}
要获取当前的实例列表(其中 result
是 Result<[Instance], Error>
)并订阅未来的更改
let cancellationToken = serviceDiscovery.subscribe(
to: service,
onNext: { result in
// This closure gets invoked once at the beginning and
// subsequently each time a change occurs
...
},
onComplete: { reason in
// This closure gets invoked when the subscription completes
...
}
)
...
// Cancel the `subscribe` request
cancellationToken.cancel()
subscribe
返回一个 CancellationToken
,可用于稍后取消订阅。onComplete
是一个闭包,当订阅结束时(例如,当服务发现实例关闭时)或通过 CancellationToken
取消时,它会被调用。CompletionReason
可用于区分导致完成的原因。
后端实现
为了成为兼容的服务发现后端,实现必须符合 ServiceDiscovery
协议,该协议包括两个方法:lookup
和 subscribe
。
func lookup(
_ service: Service,
deadline: DispatchTime?,
callback: @escaping (Result<[Instance], Error>) -> Void
)
lookup
获取给定服务的当前实例列表,并将其发送到 callback
。如果服务未知(例如,需要注册但尚未为该服务完成注册),则结果应为 LookupError.unknownService
失败。应该对操作完成的时间施加截止日期,可以通过 deadline
或默认超时来实现。
func subscribe(
to service: Service,
onNext nextResultHandler: @escaping (Result<[Instance], Error>) -> Void,
onComplete completionHandler: @escaping (CompletionReason) -> Void
) -> CancellationToken
subscribe
将服务实例“推送”到 nextResultHandler
- 当首次调用
subscribe
时,调用者应接收给定服务的当前实例列表。这本质上是lookup
的结果。 - 每当给定服务的实例列表更改时。后端实现完全控制其服务记录的更新方式和时间,但当实例列表与先前结果不同时,它必须通知
nextResultHandler
。
为每个 subscribe
请求创建一个新的 CancellationToken
。如果取消令牌的 isCancelled
为 true
,则订阅已被取消,后端实现应停止调用相应的 nextResultHandler
。
当订阅因任何原因结束时(例如,服务发现实例正在关闭或通过 CancellationToken
请求取消),后端实现还必须通过 completionHandler
发出通知,以便订阅者可以在需要时提交另一个 subscribe
请求。
项目状态
这是一个社区驱动的开源项目的开始,该项目正在积极寻求贡献。除了为 Swift Service Discovery 本身做出贡献外,我们还需要兼容的后端实现来管理服务注册和位置信息以进行查询。
参与进来
如果您对 Swift Service Discovery 感兴趣,请加入我们并参与进来!源代码已开放,我们鼓励开源社区贡献代码。如果您有反馈、问题或想讨论该项目,请随时在 Swift 论坛上交流。如果您想报告错误,请使用 GitHub 问题跟踪器。我们期待与您合作,共同推动行业朝着更好、更安全的编程未来迈进。