Skip to content

Commit

Permalink
Fixing watchOS crash and timer startup issue, fixing watchOS sample a…
Browse files Browse the repository at this point in the history
…pp (#372)

* Fixing watchOS crash and timer startup issue, fixing watchOS sample app
  • Loading branch information
MichaelGHSeg authored Nov 18, 2024
1 parent 64f8656 commit 391e40c
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 24 deletions.
6 changes: 1 addition & 5 deletions Examples/apps/BasicExample/BasicExample/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

let configuration = Configuration(writeKey: "eHitWfSPZKoXF8c6iVb6QRlIPA6P9X8G")
let configuration = Configuration(writeKey: "WRITE KEY")
.trackApplicationLifecycleEvents(true)
.flushInterval(10)
.flushAt(2)

Telemetry.shared.flushTimer = 5 * 1000
Telemetry.shared.enable = true
// Telemetry.shared.sendErrorLogData = true
// Telemetry.shared.host = "webhook.site/8d339731-c5a7-45b5-9b82-d545b6e48e6c"
analytics = Analytics(configuration: configuration)

return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class ExtensionDelegate: NSObject, WKExtensionDelegate {
.flushInterval(10)

analytics = Analytics(configuration: configuration)
analytics?.add(plugin: ConsoleLogger(name: "consoleLogger"))
analytics?.add(plugin: NotificationTracking())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
465879B22685058800180335 /* ConsoleLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 465879B12685058800180335 /* ConsoleLogger.swift */; };
465879B4268641B900180335 /* SomeScreenController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 465879B3268641B900180335 /* SomeScreenController.swift */; };
469ECD4D2684F9080028BE9A /* watchOSExample WatchKit App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 469ECD4C2684F9080028BE9A /* watchOSExample WatchKit App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
469ECD532684F9080028BE9A /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 469ECD512684F9080028BE9A /* Interface.storyboard */; };
Expand Down Expand Up @@ -65,7 +64,6 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
465879B12685058800180335 /* ConsoleLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ConsoleLogger.swift; path = ../../../other_plugins/ConsoleLogger.swift; sourceTree = "<group>"; };
465879B3268641B900180335 /* SomeScreenController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SomeScreenController.swift; sourceTree = "<group>"; };
469ECD482684F9080028BE9A /* watchOSExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = watchOSExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
469ECD4C2684F9080028BE9A /* watchOSExample WatchKit App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "watchOSExample WatchKit App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -129,7 +127,6 @@
469ECD5F2684F9090028BE9A /* watchOSExample WatchKit Extension */ = {
isa = PBXGroup;
children = (
465879B12685058800180335 /* ConsoleLogger.swift */,
469ECD602684F9090028BE9A /* InterfaceController.swift */,
465879B3268641B900180335 /* SomeScreenController.swift */,
469ECD622684F9090028BE9A /* ExtensionDelegate.swift */,
Expand Down Expand Up @@ -291,7 +288,6 @@
469ECD672684F9090028BE9A /* ComplicationController.swift in Sources */,
469ECD632684F9090028BE9A /* ExtensionDelegate.swift in Sources */,
46E73DA626F5389E0021042C /* NotificationTracking.swift in Sources */,
465879B22685058800180335 /* ConsoleLogger.swift in Sources */,
469ECD612684F9090028BE9A /* InterfaceController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
38 changes: 26 additions & 12 deletions Sources/Segment/Utilities/Telemetry.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import Foundation
import Sovran
#if os(Linux) || os(Windows)
import FoundationNetworking
#endif

public struct RemoteMetric: Codable {
let type: String
Expand Down Expand Up @@ -68,8 +71,8 @@ public class Telemetry: Subscriber {

internal var session: any HTTPSession
internal var host: String = HTTPClient.getDefaultAPIHost()
var sampleRate: Double = 0.10
private var flushTimer: Int = 30 * 1000
var sampleRate: Double = 1.0 // inital sample rate should be 1.0, will be downsampled on start
private var flushTimer: Int = 30
internal var maxQueueSize: Int = 20
var errorLogSizeMax: Int = 4000

Expand All @@ -87,7 +90,8 @@ public class Telemetry: Subscriber {
internal var started = false
private var rateLimitEndTime: TimeInterval = 0
private var telemetryQueue = DispatchQueue(label: "telemetryQueue")
private var telemetryTimer: Timer?
private var updateQueue = DispatchQueue(label: "updateQueue")
private var telemetryTimer: QueueTimer?

/// Starts the Telemetry send loop. Requires both `enable` to be set and a configuration to be retrieved from Segment.
func start() {
Expand All @@ -96,20 +100,27 @@ public class Telemetry: Subscriber {

if Double.random(in: 0...1) > sampleRate {
resetQueue()
} else {
telemetryQueue.async {
self.queue = self.queue.map { var metric = $0
metric.value = Int(Double(metric.value) / self.sampleRate)
return metric
}
}
}

telemetryTimer = Timer.scheduledTimer(withTimeInterval: TimeInterval(flushTimer) / 1000.0, repeats: true) { [weak self] _ in
self.telemetryTimer = QueueTimer(interval: .seconds(self.flushTimer), queue: .main) { [weak self] in
if (!(self?.enable ?? false)) {
self?.started = false
self?.telemetryTimer?.invalidate()
self?.telemetryTimer?.suspend()
}
self?.flush()
}
}

/// Resets the telemetry state, including the queue and seen errors.
func reset() {
telemetryTimer?.invalidate()
telemetryTimer?.suspend()
resetQueue()
seenErrors.removeAll()
started = false
Expand All @@ -121,10 +132,12 @@ public class Telemetry: Subscriber {
/// - metric: The metric name.
/// - buildTags: A closure to build the tags dictionary.
func increment(metric: String, buildTags: (inout [String: String]) -> Void) {
guard enable, sampleRate > 0.0 && sampleRate <= 1.0, metric.hasPrefix(Telemetry.METRICS_BASE_TAG), queueHasSpace() else { return }

var tags = [String: String]()
buildTags(&tags)
guard !tags.isEmpty else { return }

guard enable, sampleRate > 0.0 && sampleRate <= 1.0, metric.hasPrefix(Telemetry.METRICS_BASE_TAG), !tags.isEmpty, queueHasSpace() else { return }
if Double.random(in: 0...1) > sampleRate { return }

addRemoteMetric(metric: metric, tags: tags)
Expand All @@ -136,10 +149,11 @@ public class Telemetry: Subscriber {
/// - log: The log data.
/// - buildTags: A closure to build the tags dictionary.
func error(metric: String, log: String, buildTags: (inout [String: String]) -> Void) {
guard enable, sampleRate > 0.0 && sampleRate <= 1.0, metric.hasPrefix(Telemetry.METRICS_BASE_TAG), queueHasSpace() else { return }

var tags = [String: String]()
buildTags(&tags)

guard enable, sampleRate > 0.0 && sampleRate <= 1.0, metric.hasPrefix(Telemetry.METRICS_BASE_TAG), !tags.isEmpty, queueHasSpace() else { return }
guard !tags.isEmpty else { return }

var filteredTags = tags
if (!sendWriteKeyOnError) {
Expand Down Expand Up @@ -248,8 +262,8 @@ public class Telemetry: Subscriber {
let fullTags = tags.merging(additionalTags) { (_, new) in new }

telemetryQueue.sync {
if var found = queue.first(where: { $0.metric == metric && $0.tags == fullTags }) {
found.value += value
if let index = queue.firstIndex(where: { $0.metric == metric && $0.tags == fullTags }) {
queue[index].value += value
return
}

Expand All @@ -275,7 +289,7 @@ public class Telemetry: Subscriber {
public func subscribe(_ store: Store) {
store.subscribe(self,
initialState: true,
queue: telemetryQueue,
queue: updateQueue,
handler: systemUpdate
)
}
Expand Down
6 changes: 5 additions & 1 deletion Tests/Segment-Tests/Telemetry_Tests.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#if !os(Linux) && !os(Windows)
import XCTest

@testable import Segment

class TelemetryTests: XCTestCase {
Expand Down Expand Up @@ -163,4 +165,6 @@ class URLSessionMock: RestrictedHTTPSession {
// Mock URLSessionDataTask
class URLSessionDataTaskMock: URLSessionDataTask, @unchecked Sendable {
override func resume() {}
}
}

#endif

0 comments on commit 391e40c

Please sign in to comment.