You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Musubi/Packages/MusubiKit/Sources/MusubiCore/ConnectionWatchdog.swift

42 lines
1.4 KiB

/// Decides when a receiver counts as stalled and when to try reconnecting.
public struct ConnectionWatchdog: Sendable, Equatable {
public enum State: Equatable, Sendable {
case connecting
case live
/// No frames for a while. `retryIn` is the time until the next reconnect attempt.
case stalled(retryIn: Double)
}
public var stallAfter: Double
public var retryInterval: Double
private var lastFrame: Double?
private var lastRetry: Double?
private let startedAt: Double
public init(now: Double, stallAfter: Double = 2, retryInterval: Double = 3) {
self.startedAt = now
self.stallAfter = stallAfter
self.retryInterval = retryInterval
}
public mutating func frameArrived(at now: Double) {
lastFrame = now
lastRetry = nil
}
public func state(at now: Double) -> State {
let reference = lastFrame ?? startedAt
guard now - reference >= stallAfter else { return lastFrame == nil ? .connecting : .live }
let since = lastRetry ?? reference + stallAfter
return .stalled(retryIn: max(0, retryInterval - (now - since)))
}
/// Returns true when a reconnect should be attempted now, and records the attempt.
public mutating func shouldRetry(at now: Double) -> Bool {
guard case .stalled(let retryIn) = state(at: now), retryIn == 0 else { return false }
lastRetry = now
return true
}
}

Powered by TurnKey Linux.