From 2b58e4f6ced4510507503258f7449bfb78a03f2f Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 15 Jun 2022 11:33:03 -0700 Subject: [PATCH] add event tracking to background tasks --- apple/OmnivoreKit/Sources/App/Services.swift | 40 +++++++++++++++---- .../FetchLinkedItemsBackgroundTask.swift | 9 ++++- .../Utils/EventTracking/TrackableEvents.swift | 16 ++++++++ 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Services.swift b/apple/OmnivoreKit/Sources/App/Services.swift index 1a8d6ad59..cc394380f 100644 --- a/apple/OmnivoreKit/Sources/App/Services.swift +++ b/apple/OmnivoreKit/Sources/App/Services.swift @@ -47,35 +47,59 @@ public final class Services { } static func performBackgroundFetch(task: BGAppRefreshTask) { + let startTime = Date() Services.logger.debug("starting background fetch") scheduleBackgroundFetch() let services = Services() task.expirationHandler = { - EventTracker.trackForDebugging("background fetch expiration handler called") + EventTracker.track( + .backgroundFetch( + jobStatus: .timeExpired, + itemCount: 0, + secondsElapsed: Int(startTime.timeIntervalSinceNow) + ) + ) logger.debug("handling background fetch expiration") } guard services.authenticator.hasValidAuthToken else { - EventTracker.trackForDebugging("background fetch failed: user does not have a valid auth token") - Services.logger.debug("background fetch failed: user does not habe a valid auth token") + EventTracker.track( + .backgroundFetch( + jobStatus: .authFailure, + itemCount: 0, + secondsElapsed: Int(startTime.timeIntervalSinceNow) + ) + ) task.setTaskCompleted(success: false) return } Task { do { - try await services.dataService.fetchLinkedItemsBackgroundTask() - logger.debug("fetch complete") - EventTracker.trackForDebugging("background fetch task completed successfully") + let fetchedItemCount = try await services.dataService.fetchLinkedItemsBackgroundTask() + EventTracker.track( + .backgroundFetch( + jobStatus: .success, + itemCount: fetchedItemCount, + secondsElapsed: Int(startTime.timeIntervalSinceNow) + ) + ) task.setTaskCompleted(success: true) } catch { - logger.debug("fetch failed") - EventTracker.trackForDebugging("background fetch task failed") + EventTracker.track( + .backgroundFetch( + jobStatus: .failed, + itemCount: 0, + secondsElapsed: Int(startTime.timeIntervalSinceNow) + ) + ) task.setTaskCompleted(success: false) } } } } #endif + +// Command to simulate BG Task // e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"app.omnivore.fetchLinkedItems"] diff --git a/apple/OmnivoreKit/Sources/Services/DataService/FetchLinkedItemsBackgroundTask.swift b/apple/OmnivoreKit/Sources/Services/DataService/FetchLinkedItemsBackgroundTask.swift index 939f3330e..c3b407682 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/FetchLinkedItemsBackgroundTask.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/FetchLinkedItemsBackgroundTask.swift @@ -4,11 +4,13 @@ import Models import SwiftGraphQL extension DataService { - public func fetchLinkedItemsBackgroundTask() async throws { + public func fetchLinkedItemsBackgroundTask() async throws -> Int { + var fetchedItemCount = 0 + // Query the server for item IDs and compare against CoreData // to see what we're missing let missingItemIds = try await fetchMissingItemIDs() - guard !missingItemIds.isEmpty else { return } + guard !missingItemIds.isEmpty else { return 0 } let username: String? = await backgroundContext.perform(schedule: .immediate) { let fetchRequest: NSFetchRequest = Viewer.fetchRequest() @@ -24,8 +26,11 @@ extension DataService { for itemID in missingItemIds { // TOOD: run these in parallel logger.debug("fetching item with ID: \(itemID)") _ = try await articleContent(username: username, itemID: itemID, useCache: false) + fetchedItemCount += 1 logger.debug("done fetching item with ID: \(itemID)") } + + return fetchedItemCount } func fetchMissingItemIDs(previouslyFetchedIDs: [String] = [], cursor: String? = nil) async throws -> [String] { diff --git a/apple/OmnivoreKit/Sources/Utils/EventTracking/TrackableEvents.swift b/apple/OmnivoreKit/Sources/Utils/EventTracking/TrackableEvents.swift index 3450f1fca..0c663f231 100644 --- a/apple/OmnivoreKit/Sources/Utils/EventTracking/TrackableEvents.swift +++ b/apple/OmnivoreKit/Sources/Utils/EventTracking/TrackableEvents.swift @@ -3,6 +3,14 @@ import Foundation public enum TrackableEvent { case linkRead(linkID: String, slug: String, originalArticleURL: String) case debugMessage(message: String) + case backgroundFetch(jobStatus: BackgroundFetchJobStatus, itemCount: Int, secondsElapsed: Int) +} + +public enum BackgroundFetchJobStatus: String { + case success + case failed + case authFailure + case timeExpired } public extension TrackableEvent { @@ -12,6 +20,8 @@ public extension TrackableEvent { return "link_read" case .debugMessage: return "debug_message" + case .backgroundFetch: + return "background_fetch" } } @@ -25,6 +35,12 @@ public extension TrackableEvent { ] case let .debugMessage(message: message): return ["message": message] + case let .backgroundFetch(jobStatus: jobStatus, itemCount: itemCount, secondsElapsed: secondsElapsed): + return [ + "status": jobStatus.rawValue, + "seconds_elapsed": String(secondsElapsed), + "fetched_item_count": String(itemCount) + ] } } }