Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Remove serial queue on CachedAdBlockEngine
Browse files Browse the repository at this point in the history
  • Loading branch information
cuba committed Feb 7, 2024
1 parent 0ce75f2 commit 4d2367d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public actor AdBlockStats {
func shouldBlock(requestURL: URL, sourceURL: URL, resourceType: AdblockEngine.ResourceType, isAggressiveMode: Bool) async -> Bool {
let sources = await self.enabledSources
return await cachedEngines(for: sources).asyncConcurrentMap({ cachedEngine in
return await cachedEngine.shouldBlock(
return cachedEngine.shouldBlock(
requestURL: requestURL,
sourceURL: sourceURL,
resourceType: resourceType,
Expand Down Expand Up @@ -240,7 +240,7 @@ public actor AdBlockStats {
func cosmeticFilterModels(forFrameURL frameURL: URL, domain: Domain) async -> [CosmeticFilterModelTuple] {
return await cachedEngines(for: domain).asyncConcurrentCompactMap { cachedEngine -> CosmeticFilterModelTuple? in
do {
guard let model = try await cachedEngine.cosmeticFilterModel(forFrameURL: frameURL) else {
guard let model = try cachedEngine.cosmeticFilterModel(forFrameURL: frameURL) else {
return nil
}
return (cachedEngine.isAlwaysAggressive, model)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,85 +59,33 @@ public class CachedAdBlockEngine {
private var cachedFrameScriptTypes = FifoDict<URL, Set<UserScriptType>>()

private let engine: AdblockEngine
private let serialQueue: DispatchQueue

let isAlwaysAggressive: Bool
let filterListInfo: FilterListInfo
let resourcesInfo: ResourcesInfo

init(engine: AdblockEngine, filterListInfo: FilterListInfo, resourcesInfo: ResourcesInfo, serialQueue: DispatchQueue, isAlwaysAggressive: Bool) {
init(engine: AdblockEngine, filterListInfo: FilterListInfo, resourcesInfo: ResourcesInfo, isAlwaysAggressive: Bool) {
self.engine = engine
self.filterListInfo = filterListInfo
self.resourcesInfo = resourcesInfo
self.serialQueue = serialQueue
self.isAlwaysAggressive = isAlwaysAggressive
}

/// Checks the general and regional engines to see if the request should be blocked.
func shouldBlock(requestURL: URL, sourceURL: URL, resourceType: AdblockEngine.ResourceType, isAggressiveMode: Bool) async -> Bool {
return await withCheckedContinuation { continuation in
serialQueue.async { [weak self] in
let shouldBlock = self?.shouldBlock(
requestURL: requestURL, sourceURL: sourceURL, resourceType: resourceType,
isAggressiveMode: isAggressiveMode
) == true

continuation.resume(returning: shouldBlock)
}
}
}

/// Returns all the models for this frame URL
/// The results are cached per url, so you may call this method as many times for the same url without any performance implications.
func cosmeticFilterModel(forFrameURL frameURL: URL) async throws -> CosmeticFilterModel? {
return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<CosmeticFilterModel?, Error>) in
serialQueue.async { [weak self] in
guard let self = self else {
continuation.resume(returning: nil)
return
}

do {
if let model = try self.cachedCosmeticFilterModel(forFrameURL: frameURL) {
continuation.resume(returning: model)
} else {
continuation.resume(returning: nil)
}
} catch {
continuation.resume(throwing: error)
}
}
}
}

/// Return the selectors that need to be hidden given the frameURL, ids and classes
func selectorsForCosmeticRules(frameURL: URL, ids: [String], classes: [String]) async throws -> Set<String>? {
return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Set<String>?, Error>) in
serialQueue.async { [weak self] in
guard let self = self else {
continuation.resume(returning: nil)
return
}

do {
let model = try self.cachedCosmeticFilterModel(forFrameURL: frameURL)

let selectors = try self.engine.stylesheetForCosmeticRulesIncluding(
classes: classes, ids: ids, exceptions: model?.exceptions ?? []
)

continuation.resume(returning: Set(selectors))
} catch {
continuation.resume(throwing: error)
}
}
}
func selectorsForCosmeticRules(frameURL: URL, ids: [String], classes: [String]) throws -> Set<String>? {
let model = try self.cosmeticFilterModel(forFrameURL: frameURL)

let selectors = try self.engine.stylesheetForCosmeticRulesIncluding(
classes: classes, ids: ids, exceptions: model?.exceptions ?? []
)

return Set(selectors)
}

/// Return a cosmetic filter modelf or the given frameURL
///
/// - Warning: The caller is responsible for syncing on the `serialQueue`
private func cachedCosmeticFilterModel(forFrameURL frameURL: URL) throws -> CosmeticFilterModel? {
func cosmeticFilterModel(forFrameURL frameURL: URL) throws -> CosmeticFilterModel? {
if let result = self.cachedCosmeticFilterModels.getElement(frameURL) {
return result
}
Expand All @@ -148,7 +96,7 @@ public class CachedAdBlockEngine {
}

/// Checks the general and regional engines to see if the request should be blocked
private func shouldBlock(requestURL: URL, sourceURL: URL, resourceType: AdblockEngine.ResourceType, isAggressiveMode: Bool) -> Bool {
func shouldBlock(requestURL: URL, sourceURL: URL, resourceType: AdblockEngine.ResourceType, isAggressiveMode: Bool) -> Bool {
let key = [requestURL.absoluteString, sourceURL.absoluteString, resourceType.rawValue].joined(separator: "_")

if let cachedResult = cachedShouldBlockResult.getElement(key) {
Expand All @@ -167,15 +115,15 @@ public class CachedAdBlockEngine {
}

/// This returns all the user script types for the given frame
@MainActor func makeEngineScriptTypes(frameURL: URL, isMainFrame: Bool, domain: Domain, index: Int) async throws -> Set<UserScriptType> {
@MainActor func makeEngineScriptTypes(frameURL: URL, isMainFrame: Bool, domain: Domain, index: Int) throws -> Set<UserScriptType> {
if let userScriptTypes = cachedFrameScriptTypes.getElement(frameURL) {
return userScriptTypes
}

// Add the selectors poller scripts for this frame
var userScriptTypes: Set<UserScriptType> = []

if let source = try await cosmeticFilterModel(forFrameURL: frameURL)?.injectedScript, !source.isEmpty {
if let source = try cosmeticFilterModel(forFrameURL: frameURL)?.injectedScript, !source.isEmpty {
let configuration = UserScriptType.EngineScriptConfiguration(
frameURL: frameURL, isMainFrame: isMainFrame, source: source, order: index,
isDeAMPEnabled: Preferences.Shields.autoRedirectAMPPages.value
Expand Down Expand Up @@ -206,12 +154,11 @@ public class CachedAdBlockEngine {

do {
let engine = try AdblockEngine(textFileURL: filterListInfo.localFileURL, resourcesFileURL: resourcesInfo.localFileURL)
let serialQueue = DispatchQueue(label: "com.brave.WrappedAdBlockEngine.\(UUID().uuidString)")
Self.signpost.endInterval("compileEngine", state)

return CachedAdBlockEngine(
engine: engine, filterListInfo: filterListInfo, resourcesInfo: resourcesInfo,
serialQueue: serialQueue, isAlwaysAggressive: isAlwaysAggressive
isAlwaysAggressive: isAlwaysAggressive
)
} catch {
Self.signpost.endInterval("compileEngine", state, "\(error.localizedDescription)")
Expand Down

0 comments on commit 4d2367d

Please sign in to comment.