Skip to content

Commit

Permalink
Restore background activity
Browse files Browse the repository at this point in the history
  • Loading branch information
joewalsh committed Sep 24, 2020
1 parent 85c3838 commit 4fb6c32
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions WMF Framework/WidgetController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ public final class WidgetController: NSObject {
getRetainedSharedDataStore { dataStore in
task(dataStore, { result in
DispatchQueue.main.async {
self.releaseSharedDataStore()
DispatchQueue.main.async {
self.releaseSharedDataStore {
userCompletion(result)
}
}
Expand All @@ -49,6 +48,7 @@ public final class WidgetController: NSObject {
private var _dataStore: MWKDataStore?
private var completions: [(MWKDataStore) -> Void] = []
private var isCreatingDataStore: Bool = false
private var backgroundActivity: NSObjectProtocol?

/// Returns a `MWKDataStore`for use with widget updates.
/// Manages a shared instance and a reference count for use by multiple widgets.
Expand All @@ -65,6 +65,7 @@ public final class WidgetController: NSObject {
return
}
isCreatingDataStore = true
backgroundActivity = ProcessInfo.processInfo.beginActivity(options: [.background, .suddenTerminationDisabled, .automaticTerminationDisabled], reason: "Wikipedia Extension - " + UUID().uuidString)
let dataStore = MWKDataStore()
dataStore.performLibraryUpdates {
DispatchQueue.main.async {
Expand All @@ -79,21 +80,28 @@ public final class WidgetController: NSObject {
}

/// Releases the shared `MWKDataStore` returned by `getRetainedSharedDataStore()`.
private func releaseSharedDataStore() {
private func releaseSharedDataStore(completion: @escaping () -> Void) {
assert(Thread.isMainThread, "Data store must be released from the main queue")
dataStoreRetainCount -= 1
guard dataStoreRetainCount <= 0 else {
return
}
_dataStore = nil
dataStoreRetainCount = 0
#if DEBUG
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
let asyncBackgroundActivity = backgroundActivity
// Give a bit of a buffer for other async activity to cease
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(10)) {
completion()
if let asyncBackgroundActivity = asyncBackgroundActivity {
ProcessInfo.processInfo.endActivity(asyncBackgroundActivity)
}
#if DEBUG
let openFiles = self.openFilePaths()
let openSqliteFile = openFiles.first(where: { $0.hasSuffix(".sqlite") })
assert(openSqliteFile == nil, "There should be no open sqlite files (which in our case are Core Data persistent stores) in the shared app container after the data store is released. The widget still has a lock on these files: \(openFiles)")
#endif
}
#endif
backgroundActivity = nil
}

#if DEBUG
Expand Down

0 comments on commit 4fb6c32

Please sign in to comment.