import Foundation /// An objec thatt provides the RTMPConnection, SRTConnection's monitoring events. package final actor NetworkMonitor { /// The error domain codes. public enum Error: Swift.Error { /// An invalid internal stare. case invalidState } /// An asynchronous sequence for network monitoring event. public var event: AsyncStream { AsyncStream { continuation in self.continuation = continuation } } public private(set) var isRunning = false private var timer: Task? { didSet { oldValue?.cancel() } } private var measureInterval = 3 private var currentBytesInPerSecond = 0 private var currentBytesOutPerSecond = 0 private var previousTotalBytesIn = 0 private var previousTotalBytesOut = 0 private var previousQueueBytesOut: [Int] = [] private var continuation: AsyncStream.Continuation? { didSet { oldValue?.finish() } } private weak var reporter: (any NetworkTransportReporter)? /// Creates a new instance. package init(_ reporter: some NetworkTransportReporter) { self.reporter = reporter } private func collect() async throws -> NetworkMonitorEvent { guard let report = await reporter?.makeNetworkTransportReport() else { throw Error.invalidState } let totalBytesIn = report.totalBytesIn let totalBytesOut = report.totalBytesOut let queueBytesOut = report.queueBytesOut currentBytesInPerSecond = totalBytesIn - previousTotalBytesIn currentBytesOutPerSecond = totalBytesOut - previousTotalBytesOut previousTotalBytesIn = totalBytesIn previousTotalBytesOut = totalBytesOut previousQueueBytesOut.append(queueBytesOut) let eventReport = NetworkMonitorReport( totalBytesIn: totalBytesIn, totalBytesOut: totalBytesOut, currentQueueBytesOut: queueBytesOut, currentBytesInPerSecond: currentBytesInPerSecond, currentBytesOutPerSecond: currentBytesOutPerSecond ) if measureInterval <= previousQueueBytesOut.count { defer { previousQueueBytesOut.removeFirst() } var total = 0 for i in 0..