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

Commit

Permalink
Load cached data for default filter list
Browse files Browse the repository at this point in the history
  • Loading branch information
cuba committed Aug 19, 2022
1 parent 542452c commit 9774b32
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 45 deletions.
7 changes: 7 additions & 0 deletions Client/Frontend/ClientPreferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ extension Preferences {
///
/// Value should only be checked on launch
public static let backgroundedCleanly = Option<Bool>(key: "appstate.backgrounded-cleanly", default: true)

/// A cached value for the last folder path we got for filter lists
///
/// This is a useful setting because it take too long for filter lists to load during launch
/// and therefore we can try to load them right away and have them ready on the first tab load
static let lastDefaultFilterListFolderPath =
Option<String?>(key: "caching.last-default-filter-list-folder-path", default: nil)
}
}

Expand Down
63 changes: 34 additions & 29 deletions Client/WebFilters/FilterListResourceDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Combine
import Data
import BraveCore
import Shared
import BraveShared

private let log = Logger.browserLogger

Expand Down Expand Up @@ -52,56 +53,59 @@ public class FilterListResourceDownloader: ObservableObject {
}

public func loadCachedData() async {
let filterListSettings: [FilterListSetting] = await Task { @MainActor in
await withTaskGroup(of: Void.self) { group in
group.addTask {
await self.loadCachedFilterLists()
}
group.addTask {
await self.loadCachedDefaultFilterList()
}
}
}

private func loadCachedFilterLists() async {
let settingsInfo: [(uuid: String, folderURL: URL?, resources: [ResourceDownloader.Resource])] = await Task { @MainActor in
let filterListSettings = FilterListSetting.allSettings()
self.filterListSettings = filterListSettings
return filterListSettings

return filterListSettings.compactMap { setting in
guard setting.isEnabled else { return nil }
return (setting.uuid, setting.folderURL, setting.persistedResources)
}
}.value

await withTaskGroup(of: Void.self) { group in
for filterListSetting in filterListSettings {
return await withTaskGroup(of: Void.self) { group in
for settingInfo in settingsInfo {
group.addTask {
// Get uuid
// Need to fetch this on the main thread
let uuid: String = await Task { @MainActor in
return filterListSetting.uuid
}.value

// Get folderURL
// Need to fetch this on the main thread
let folderURL: URL? = await Task { @MainActor in
guard filterListSetting.isEnabled else { return nil }
return filterListSetting.folderURL
}.value

// Get perseisted resources
// Need to fetch this on the main thread
let resources: [ResourceDownloader.Resource] = await Task { @MainActor in
guard filterListSetting.isEnabled else { return [] }
return filterListSetting.persistedResources
}.value

// Load cached component updater files
if let folderURL = folderURL, FileManager.default.fileExists(atPath: folderURL.path) {
await self.handle(downloadedFolderURL: folderURL, forFilterListUUID: uuid)
if let folderURL = settingInfo.folderURL, FileManager.default.fileExists(atPath: folderURL.path) {
await self.handle(downloadedFolderURL: folderURL, forFilterListUUID: settingInfo.uuid)
}

// Load cached download resources
await withTaskGroup(of: Void.self) { group in
for resource in resources {
for resource in settingInfo.resources {
group.addTask {
guard let fileURL = ResourceDownloader.downloadedFileURL(for: resource) else { return }
let date = try? ResourceDownloader.creationDate(for: resource)
await self.handle(downloadedFileURL: fileURL, for: resource, filterListUUID: uuid, date: date)
await self.handle(downloadedFileURL: fileURL, for: resource, filterListUUID: settingInfo.uuid, date: date)
}
}
}
}

}
}
}

private func loadCachedDefaultFilterList() async {
guard let folderURL = FilterListSetting.makeFolderURL(
forFilterListFolderPath: Preferences.AppState.lastDefaultFilterListFolderPath.value
), FileManager.default.fileExists(atPath: folderURL.path) else {
return
}

// TODO: @JS Load the default sheilds from cache. But we need to store the folder URL somewhere
await loadShields(fromFolderURL: folderURL)
}

/// Start the resource subscriber.
Expand Down Expand Up @@ -178,6 +182,7 @@ public class FilterListResourceDownloader: ObservableObject {
Task.detached {
for await folderURL in await adBlockService.shieldsInstallDirectoryURLStream() {
guard let folderURL = folderURL else { continue }
Preferences.AppState.lastDefaultFilterListFolderPath.value = FilterListSetting.extractFolderPath(fromFilterListFolderURL: folderURL)
await self.loadShields(fromFolderURL: folderURL)
}
}
Expand Down
39 changes: 23 additions & 16 deletions Sources/Data/models/FilterListSetting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ private let log = Logger.browserLogger

public final class FilterListSetting: NSManagedObject, CRUD {
/// The directory to which we should store all the dowloaded files into
private static var baseURL: URL? {
private static var filterListBaseFolderURL: URL? {
let location = FileManager.SearchPathDirectory.applicationSupportDirectory
return FileManager.default.urls(for: location, in: .userDomainMask).first
}
Expand All @@ -23,24 +23,11 @@ public final class FilterListSetting: NSManagedObject, CRUD {

public var folderURL: URL? {
get {
// Combine the path with the base URL
guard let folderPath = folderPath else { return nil }
return Self.baseURL?.appendingPathComponent(folderPath)
return Self.makeFolderURL(forFilterListFolderPath: folderPath)
}
set {
// We need to extract the path. We don't want to store the full URL
guard let baseURL = Self.baseURL, let folderURL = newValue else {
folderPath = nil
return
}

// We take the path after the base url
if let range = folderURL.path.range(of: baseURL.path) {
let folderPath = folderURL.path[range.upperBound...]
self.folderPath = String(folderPath)
} else {
folderPath = nil
}
self.folderPath = Self.extractFolderPath(fromFilterListFolderURL: newValue)
}
}

Expand Down Expand Up @@ -96,4 +83,24 @@ public final class FilterListSetting: NSManagedObject, CRUD {
public static func entity(_ context: NSManagedObjectContext) -> NSEntityDescription {
return NSEntityDescription.entity(forEntityName: "FilterListSetting", in: context)!
}

public static func makeFolderURL(forFilterListFolderPath folderPath: String?) -> URL? {
// Combine the path with the base URL
guard let folderPath = folderPath else { return nil }
return filterListBaseFolderURL?.appendingPathComponent(folderPath)
}

public static func extractFolderPath(fromFilterListFolderURL folderURL: URL?) -> String? {
guard let baseURL = filterListBaseFolderURL, let folderURL = folderURL else {
return nil
}

// We take the path after the base url
if let range = folderURL.path.range(of: baseURL.path) {
let folderPath = folderURL.path[range.upperBound...]
return String(folderPath)
} else {
return nil
}
}
}

0 comments on commit 9774b32

Please sign in to comment.