punchnet-macos/Tun/Punchnet/NWPath/SDLPathDebounceActor.swift

55 lines
1.3 KiB
Swift

//
// SDLPathDebounceActor.swift
// punchnet
//
// Created by on 2026/4/29.
//
import Foundation
import Network
actor SDLPathDebounceActor {
private var lastSnapshot: SDLPathSnapshot?
private var debounceTask: Task<Void, Never>?
private let delay: Duration
public let statusStream: AsyncStream<NWPath.Status>
private let statusCont: AsyncStream<NWPath.Status>.Continuation
init(delay: Duration = .seconds(2)) {
self.delay = delay
let (stream, cont) = AsyncStream.makeStream(of: NWPath.Status.self)
self.statusStream = stream
self.statusCont = cont
}
func submit(_ snapshot: SDLPathSnapshot) {
guard snapshot != lastSnapshot else {
return
}
self.lastSnapshot = snapshot
self.debounceTask?.cancel()
self.debounceTask = Task { [delay] in
try? await Task.sleep(for: delay)
guard !Task.isCancelled else {
return
}
await self.handleStableSnapshot(snapshot)
}
}
private func handleStableSnapshot(_ snapshot: SDLPathSnapshot) async {
self.statusCont.yield(snapshot.status)
}
func stop() {
debounceTask?.cancel()
debounceTask = nil
}
}