mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-13 15:54:10 +09:00
feat: added jitter to the network module that is calculated from the ICMP signals
This commit is contained in:
@@ -107,6 +107,7 @@ public struct Network_Usage: Codable, RemoteType {
|
||||
public struct Network_Connectivity: Codable {
|
||||
var status: Bool = false
|
||||
var latency: Double = 0
|
||||
var jitter: Double = 0
|
||||
}
|
||||
|
||||
public struct Network_Process: Codable, Process_p {
|
||||
|
||||
@@ -38,6 +38,7 @@ internal class Popup: PopupWrapper {
|
||||
private var statusField: ValueField? = nil
|
||||
private var connectivityField: ValueField? = nil
|
||||
private var latencyField: ValueField? = nil
|
||||
private var jitterField: ValueField? = nil
|
||||
|
||||
private var interfaceView: NSStackView? = nil
|
||||
private var interfaceField: ValueField? = nil
|
||||
@@ -82,6 +83,7 @@ internal class Popup: PopupWrapper {
|
||||
|
||||
private var lastReset: Date = Date()
|
||||
private var latency: [Double] = []
|
||||
private var jitter: [Double] = []
|
||||
|
||||
private var base: DataSizeBase {
|
||||
DataSizeBase(rawValue: Store.shared.string(key: "\(self.title)_base", defaultValue: "byte")) ?? .byte
|
||||
@@ -274,6 +276,7 @@ internal class Popup: PopupWrapper {
|
||||
self.statusField = popupRow(view, title: "\(localizedString("Status")):", value: localizedString("Unknown")).1
|
||||
self.connectivityField = popupRow(view, title: "\(localizedString("Internet connection")):", value: localizedString("Unknown")).1
|
||||
self.latencyField = popupRow(view, title: "\(localizedString("Latency")):", value: "0 ms").1
|
||||
self.jitterField = popupRow(view, title: "\(localizedString("Jitter")):", value: "0 ms").1
|
||||
|
||||
return view
|
||||
}
|
||||
@@ -602,18 +605,30 @@ internal class Popup: PopupWrapper {
|
||||
}
|
||||
self.latency.append(value?.latency ?? 0)
|
||||
|
||||
if self.jitter.count >= 90 {
|
||||
self.jitter.remove(at: 0)
|
||||
}
|
||||
self.jitter.append(value?.jitter ?? 0)
|
||||
|
||||
DispatchQueue.main.async(execute: {
|
||||
if (self.window?.isVisible ?? false) || !self.connectionInitialized {
|
||||
var text = "Unknown"
|
||||
var latency = localizedString("Unknown")
|
||||
var jitter = localizedString("Unknown")
|
||||
|
||||
if let v = value {
|
||||
text = v.status ? "UP" : "DOWN"
|
||||
if v.status && !self.latency.isEmpty {
|
||||
latency = "\((self.latency.reduce(0, +) / Double(self.latency.count)).rounded(toPlaces: 2)) ms"
|
||||
}
|
||||
if v.status && !self.jitter.isEmpty {
|
||||
jitter = "\((self.jitter.reduce(0, +) / Double(self.jitter.count)).rounded(toPlaces: 2)) ms"
|
||||
}
|
||||
}
|
||||
self.connectivityField?.stringValue = localizedString(text)
|
||||
self.latencyField?.stringValue = latency
|
||||
self.jitterField?.stringValue = jitter
|
||||
|
||||
self.connectivityField?.stringValue = localizedString(text)
|
||||
self.connectionInitialized = true
|
||||
}
|
||||
|
||||
|
||||
@@ -742,6 +742,18 @@ internal class ConnectivityReader: Reader<Network_Connectivity> {
|
||||
set { self.variablesQueue.sync { self._latency = newValue } }
|
||||
}
|
||||
|
||||
private var _previousLatency: Double? = nil
|
||||
private var previousLatency: Double? {
|
||||
get { self.variablesQueue.sync { self._previousLatency } }
|
||||
set { self.variablesQueue.sync { self._previousLatency = newValue } }
|
||||
}
|
||||
|
||||
private var _jitter: Double? = nil
|
||||
private var jitter: Double? {
|
||||
get { self.variablesQueue.sync { self._jitter } }
|
||||
set { self.variablesQueue.sync { self._jitter = newValue } }
|
||||
}
|
||||
|
||||
var start: DispatchTime? = nil
|
||||
|
||||
private struct ICMPHeader {
|
||||
@@ -817,6 +829,9 @@ internal class ConnectivityReader: Reader<Network_Connectivity> {
|
||||
if let l = self.latency {
|
||||
self.wrapper.latency = l
|
||||
}
|
||||
if let j = self.jitter {
|
||||
self.wrapper.jitter = j
|
||||
}
|
||||
self.callback(self.wrapper)
|
||||
}
|
||||
}
|
||||
@@ -831,6 +846,17 @@ internal class ConnectivityReader: Reader<Network_Connectivity> {
|
||||
let end = DispatchTime.now()
|
||||
|
||||
self.latency = Double(end.uptimeNanoseconds - (self.start?.uptimeNanoseconds ?? 0)) / 1_000_000
|
||||
|
||||
if let prev = self.previousLatency {
|
||||
let d = abs((self.latency ?? 0) - prev)
|
||||
if self.jitter == nil {
|
||||
self.jitter = d
|
||||
} else {
|
||||
self.jitter! += (d - self.jitter!) / 16.0
|
||||
}
|
||||
}
|
||||
self.previousLatency = self.latency
|
||||
|
||||
self.status = error == nil
|
||||
self.isPinging = false
|
||||
self.timeoutTimer?.invalidate()
|
||||
|
||||
Reference in New Issue
Block a user