From 80ced96f08c01fd8f33e35cbfc245b40f1005f31 Mon Sep 17 00:00:00 2001 From: smodi Date: Mon, 2 Dec 2024 16:01:30 -0800 Subject: [PATCH] Initial changes for compilation time tracking. --- .../ContentBlockerRulesManager.swift | 20 +++++++++---------- .../ContentBlockingRulesCompilationTask.swift | 12 +++++++++-- .../ContentBlockingRulesLookupTask.swift | 10 ++++++---- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Sources/BrowserServicesKit/ContentBlocking/ContentBlockerRulesManager.swift b/Sources/BrowserServicesKit/ContentBlocking/ContentBlockerRulesManager.swift index c2de45764..dd2601ca2 100644 --- a/Sources/BrowserServicesKit/ContentBlocking/ContentBlockerRulesManager.swift +++ b/Sources/BrowserServicesKit/ContentBlocking/ContentBlockerRulesManager.swift @@ -79,7 +79,7 @@ public class ContentBlockerRulesManager: CompiledRuleListsSource { self.identifier = identifier } - internal init(compilationResult: (compiledRulesList: WKContentRuleList, model: ContentBlockerRulesSourceModel)) { + internal init(compilationResult: CompilationResult) { let surrogateTDS = ContentBlockerRulesManager.extractSurrogates(from: compilationResult.model.tds) let encodedData = try? JSONEncoder().encode(surrogateTDS) let encodedTrackerData = String(data: encodedData!, encoding: .utf8)! @@ -130,7 +130,6 @@ public class ContentBlockerRulesManager: CompiledRuleListsSource { public var sourceManagers = [String: ContentBlockerRulesSourceManager]() private var currentTasks = [CompilationTask]() - private var compilationStartTime: TimeInterval? private let workQueue = DispatchQueue(label: "ContentBlockerManagerQueue", qos: .userInitiated) @@ -229,7 +228,6 @@ public class ContentBlockerRulesManager: CompiledRuleListsSource { } state = .recompiling(currentTokens: [token]) - compilationStartTime = compilationStartTime ?? CACurrentMediaTime() lock.unlock() return true } @@ -388,6 +386,15 @@ public class ContentBlockerRulesManager: CompiledRuleListsSource { unprotectedSitesHash: nil)) } + if let compilationTime = result.compilationTime { + + //todo: map broken sources to iteration count + let iteration = task.sourceManager.brokenSources + + //todo: need to change this to the updated format with time range and iteration + self.errorReporting?.fire(.contentBlockingCompilationTime, parameters: ["compilationTime": String(compilationTime)]) + } + changes[task.rulesList.name] = diff return rules } @@ -404,7 +411,6 @@ public class ContentBlockerRulesManager: CompiledRuleListsSource { _currentRules = rules let completionTokens: [CompletionToken] - let compilationTime = compilationStartTime.map { start in CACurrentMediaTime() - start } switch state { case .recompilingAndScheduled(let currentTokens, let pendingTokens): // New work has been scheduled - prepare for execution. @@ -414,12 +420,10 @@ public class ContentBlockerRulesManager: CompiledRuleListsSource { completionTokens = currentTokens state = .recompiling(currentTokens: pendingTokens) - compilationStartTime = CACurrentMediaTime() case .recompiling(let currentTokens): completionTokens = currentTokens state = .idle - compilationStartTime = nil case .idle: assertionFailure("Unexpected state") @@ -432,10 +436,6 @@ public class ContentBlockerRulesManager: CompiledRuleListsSource { updatesSubject.send(UpdateEvent(rules: rules, changes: changes, completionTokens: completionTokens)) DispatchQueue.main.async { - if let compilationTime = compilationTime { - self.errorReporting?.fire(.contentBlockingCompilationTime, parameters: ["compilationTime": String(compilationTime)]) - } - self.cleanup(currentIdentifiers: currentIdentifiers) } } diff --git a/Sources/BrowserServicesKit/ContentBlocking/ContentBlockingRulesCompilationTask.swift b/Sources/BrowserServicesKit/ContentBlocking/ContentBlockingRulesCompilationTask.swift index eee791ff5..5dd6a387d 100644 --- a/Sources/BrowserServicesKit/ContentBlocking/ContentBlockingRulesCompilationTask.swift +++ b/Sources/BrowserServicesKit/ContentBlocking/ContentBlockingRulesCompilationTask.swift @@ -23,18 +23,21 @@ import TrackerRadarKit import os.log extension ContentBlockerRulesManager { + typealias CompilationResult = (compiledRulesList: WKContentRuleList, model: ContentBlockerRulesSourceModel, compilationTime: TimeInterval?) /** Encapsulates compilation steps for a single Task */ internal class CompilationTask { typealias Completion = (_ task: CompilationTask, _ success: Bool) -> Void + let workQueue: DispatchQueue let rulesList: ContentBlockerRulesList let sourceManager: ContentBlockerRulesSourceManager var isCompleted: Bool { result != nil || compilationImpossible } private(set) var compilationImpossible = false - private(set) var result: (compiledRulesList: WKContentRuleList, model: ContentBlockerRulesSourceModel)? + private(set) var result: CompilationResult? + private(set) var compilationStartTime: TimeInterval? init(workQueue: DispatchQueue, rulesList: ContentBlockerRulesList, @@ -52,6 +55,8 @@ extension ContentBlockerRulesManager { completionHandler(self, false) return } + + self.compilationStartTime = CACurrentMediaTime() guard !ignoreCache else { Logger.contentBlocking.log("❗️ ignoring cache") @@ -65,6 +70,7 @@ extension ContentBlockerRulesManager { DispatchQueue.main.async { let identifier = model.rulesIdentifier.stringValue Logger.contentBlocking.debug("Lookup CBR with \(identifier, privacy: .public)") + //Todo: how do we exclude this case from compilation time where the result is returned from cache WKContentRuleListStore.default()?.lookUpContentRuleList(forIdentifier: identifier) { ruleList, _ in if let ruleList = ruleList { Logger.contentBlocking.log("🟢 CBR loaded from cache: \(self.rulesList.name, privacy: .public)") @@ -83,7 +89,9 @@ extension ContentBlockerRulesManager { model: ContentBlockerRulesSourceModel, completionHandler: @escaping Completion) { workQueue.async { - self.result = (compiledRulesList, model) + let compilationTime = self.compilationStartTime.map { start in CACurrentMediaTime() - start } + + self.result = (compiledRulesList, model, compilationTime) completionHandler(self, true) } } diff --git a/Sources/BrowserServicesKit/ContentBlocking/ContentBlockingRulesLookupTask.swift b/Sources/BrowserServicesKit/ContentBlocking/ContentBlockingRulesLookupTask.swift index 974c984ac..c57bc158d 100644 --- a/Sources/BrowserServicesKit/ContentBlocking/ContentBlockingRulesLookupTask.swift +++ b/Sources/BrowserServicesKit/ContentBlocking/ContentBlockingRulesLookupTask.swift @@ -24,11 +24,13 @@ extension ContentBlockerRulesManager { final class LookupRulesTask { - typealias LookupResult = (compiledRulesList: WKContentRuleList, model: ContentBlockerRulesSourceModel) + //This type has been overloaded multiple times, I'm collapsing them all into CompilationResult type + //typealias LookupResult = (compiledRulesList: WKContentRuleList, model: ContentBlockerRulesSourceModel) private let sourceManagers: [ContentBlockerRulesSourceManager] - public private(set) var result: [LookupResult]? + ////todo: how to get around calling this compilation result when in lookuptask? + public private(set) var result: [CompilationResult]? init(sourceManagers: [ContentBlockerRulesSourceManager]) { self.sourceManagers = sourceManagers @@ -36,7 +38,7 @@ extension ContentBlockerRulesManager { func lookupCachedRulesLists() async throws { - var result = [LookupResult]() + var result = [CompilationResult]() for sourceManager in sourceManagers { guard let model = sourceManager.makeModel() else { throw WKError(.contentRuleListStoreLookUpFailed) @@ -49,7 +51,7 @@ extension ContentBlockerRulesManager { throw WKError(.contentRuleListStoreLookUpFailed) } - result.append((ruleList, model)) + result.append((ruleList, model, nil)) } self.result = result }