mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +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 {
|
public struct Network_Connectivity: Codable {
|
||||||
var status: Bool = false
|
var status: Bool = false
|
||||||
var latency: Double = 0
|
var latency: Double = 0
|
||||||
|
var jitter: Double = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Network_Process: Codable, Process_p {
|
public struct Network_Process: Codable, Process_p {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ internal class Popup: PopupWrapper {
|
|||||||
private var statusField: ValueField? = nil
|
private var statusField: ValueField? = nil
|
||||||
private var connectivityField: ValueField? = nil
|
private var connectivityField: ValueField? = nil
|
||||||
private var latencyField: ValueField? = nil
|
private var latencyField: ValueField? = nil
|
||||||
|
private var jitterField: ValueField? = nil
|
||||||
|
|
||||||
private var interfaceView: NSStackView? = nil
|
private var interfaceView: NSStackView? = nil
|
||||||
private var interfaceField: ValueField? = nil
|
private var interfaceField: ValueField? = nil
|
||||||
@@ -82,6 +83,7 @@ internal class Popup: PopupWrapper {
|
|||||||
|
|
||||||
private var lastReset: Date = Date()
|
private var lastReset: Date = Date()
|
||||||
private var latency: [Double] = []
|
private var latency: [Double] = []
|
||||||
|
private var jitter: [Double] = []
|
||||||
|
|
||||||
private var base: DataSizeBase {
|
private var base: DataSizeBase {
|
||||||
DataSizeBase(rawValue: Store.shared.string(key: "\(self.title)_base", defaultValue: "byte")) ?? .byte
|
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.statusField = popupRow(view, title: "\(localizedString("Status")):", value: localizedString("Unknown")).1
|
||||||
self.connectivityField = popupRow(view, title: "\(localizedString("Internet connection")):", 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.latencyField = popupRow(view, title: "\(localizedString("Latency")):", value: "0 ms").1
|
||||||
|
self.jitterField = popupRow(view, title: "\(localizedString("Jitter")):", value: "0 ms").1
|
||||||
|
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
@@ -602,18 +605,30 @@ internal class Popup: PopupWrapper {
|
|||||||
}
|
}
|
||||||
self.latency.append(value?.latency ?? 0)
|
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: {
|
DispatchQueue.main.async(execute: {
|
||||||
if (self.window?.isVisible ?? false) || !self.connectionInitialized {
|
if (self.window?.isVisible ?? false) || !self.connectionInitialized {
|
||||||
var text = "Unknown"
|
var text = "Unknown"
|
||||||
var latency = localizedString("Unknown")
|
var latency = localizedString("Unknown")
|
||||||
|
var jitter = localizedString("Unknown")
|
||||||
|
|
||||||
if let v = value {
|
if let v = value {
|
||||||
text = v.status ? "UP" : "DOWN"
|
text = v.status ? "UP" : "DOWN"
|
||||||
if v.status && !self.latency.isEmpty {
|
if v.status && !self.latency.isEmpty {
|
||||||
latency = "\((self.latency.reduce(0, +) / Double(self.latency.count)).rounded(toPlaces: 2)) ms"
|
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.latencyField?.stringValue = latency
|
||||||
|
self.jitterField?.stringValue = jitter
|
||||||
|
|
||||||
|
self.connectivityField?.stringValue = localizedString(text)
|
||||||
self.connectionInitialized = true
|
self.connectionInitialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -742,6 +742,18 @@ internal class ConnectivityReader: Reader<Network_Connectivity> {
|
|||||||
set { self.variablesQueue.sync { self._latency = newValue } }
|
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
|
var start: DispatchTime? = nil
|
||||||
|
|
||||||
private struct ICMPHeader {
|
private struct ICMPHeader {
|
||||||
@@ -817,6 +829,9 @@ internal class ConnectivityReader: Reader<Network_Connectivity> {
|
|||||||
if let l = self.latency {
|
if let l = self.latency {
|
||||||
self.wrapper.latency = l
|
self.wrapper.latency = l
|
||||||
}
|
}
|
||||||
|
if let j = self.jitter {
|
||||||
|
self.wrapper.jitter = j
|
||||||
|
}
|
||||||
self.callback(self.wrapper)
|
self.callback(self.wrapper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -831,6 +846,17 @@ internal class ConnectivityReader: Reader<Network_Connectivity> {
|
|||||||
let end = DispatchTime.now()
|
let end = DispatchTime.now()
|
||||||
|
|
||||||
self.latency = Double(end.uptimeNanoseconds - (self.start?.uptimeNanoseconds ?? 0)) / 1_000_000
|
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.status = error == nil
|
||||||
self.isPinging = false
|
self.isPinging = false
|
||||||
self.timeoutTimer?.invalidate()
|
self.timeoutTimer?.invalidate()
|
||||||
|
|||||||
Reference in New Issue
Block a user