Skip to content

Commit

Permalink
Try and fix Realm crashes via excessive background tasks (#1874)
Browse files Browse the repository at this point in the history
Starting in iOS 15, there's a number of crashes happening in the background with Realm. They don't appear to be due to the file lock in the shared app container, but this may help resolve them either way -- easy to see if the next beta doesn't crash a bunch.
  • Loading branch information
zacwest authored Oct 3, 2021
1 parent a746086 commit 7cbde6d
Show file tree
Hide file tree
Showing 27 changed files with 138 additions and 175 deletions.
2 changes: 1 addition & 1 deletion Sources/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
text: "Application Starting" + (launchingForLocation ? " due to location change" : ""),
type: .unknown
)
Current.clientEventStore.addEvent(event)
Current.clientEventStore.addEvent(event).cauterize()

zoneManager = ZoneManager()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public class ClientEventTableViewController: UITableViewController, UISearchResu
alertController.popoverPresentationController?.barButtonItem = sender

alertController.addAction(UIAlertAction(title: L10n.ClientEvents.View.clear, style: .destructive) { _ in
Current.clientEventStore.clearAllEvents()
Current.clientEventStore.clearAllEvents().cauterize()
})
alertController.addAction(UIAlertAction(title: L10n.cancelLabel, style: .cancel, handler: nil))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class LocationHistoryListViewController: HAFormViewController {

@objc private func clear(_ sender: AnyObject?) {
let realm = Current.realm()
try? realm.write {
realm.reentrantWrite {
realm.delete(realm.objects(LocationHistoryEntry.self))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,27 @@ class ComplicationEditViewController: HAFormViewController, TypedRowControllerTy
}

@objc private func save() {
do {
let realm = Current.realm()
try realm.write {
if let name = (form.rowBy(tag: "name") as? TextRow)?.value, name.isEmpty == false {
config.name = name
} else {
config.name = nil
}
if let IsPublic = (form.rowBy(tag: "IsPublic") as? SwitchRow)?.value {
config.IsPublic = IsPublic
} else {
config.IsPublic = true
}
config.Template = displayTemplate
config.Data = getValuesGroupedBySection()

Current.Log.verbose("COMPLICATION \(config) \(config.Data)")

realm.add(config, update: .all)
let realm = Current.realm()
realm.reentrantWrite {
if let name = (form.rowBy(tag: "name") as? TextRow)?.value, name.isEmpty == false {
config.name = name
} else {
config.name = nil
}
} catch {
Current.Log.error(error)
}
if let IsPublic = (form.rowBy(tag: "IsPublic") as? SwitchRow)?.value {
config.IsPublic = IsPublic
} else {
config.IsPublic = true
}
config.Template = displayTemplate
config.Data = getValuesGroupedBySection()

Current.Log.verbose("COMPLICATION \(config) \(config.Data)")

Current.api.then(on: nil) { api in
realm.add(config, update: .all)
}.then(on: nil) {
Current.api
}.then(on: nil) { api in
api.updateComplications(passively: false)
}.cauterize()

Expand All @@ -76,15 +72,11 @@ class ComplicationEditViewController: HAFormViewController, TypedRowControllerTy
alert.addAction(UIAlertAction(
title: L10n.Watch.Configurator.Delete.button, style: .destructive, handler: { [config] _ in
let realm = Current.realm()
do {
try realm.write {
realm.delete(config)
}
} catch {
Current.Log.error(error)
}

Current.api.then(on: nil) { api in
realm.reentrantWrite {
realm.delete(config)
}.then(on: nil) {
Current.api
}.then(on: nil) { api in
api.updateComplications(passively: false)
}.cauterize()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,7 @@ class NotificationActionConfigurator: HAFormViewController, TypedRowControllerTy

let formVals = form.values(includeHidden: true)

// swiftlint:disable:next force_try
try! realm.write {
realm.reentrantWrite {
// swiftlint:disable force_cast
if self.newAction {
self.action.Identifier = formVals["identifier"] as! String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,8 @@ class NotificationCategoryConfigurator: HAFormViewController, TypedRowController
if !newCategory {
$0.value = self.category.Name
}
}.onChange { row in
// swiftlint:disable:next force_try
try! self.realm.write {
}.onChange { [realm] row in
realm.reentrantWrite {
if let value = row.value {
self.category.Name = value
}
Expand All @@ -141,9 +140,8 @@ class NotificationCategoryConfigurator: HAFormViewController, TypedRowController
$0.value = self.category.Identifier
$0.disabled = true
}
}.onChange { row in
// swiftlint:disable:next force_try
try! self.realm.write {
}.onChange { [realm] row in
realm.reentrantWrite {
if let value = row.value {
self.category.Identifier = value
}
Expand All @@ -167,9 +165,8 @@ class NotificationCategoryConfigurator: HAFormViewController, TypedRowController
} else {
$0.value = L10n.NotificationsConfigurator.Category.Rows.HiddenPreviewPlaceholder.default
}
}.onChange { row in
// swiftlint:disable:next force_try
try! self.realm.write {
}.onChange { [realm] row in
realm.reentrantWrite {
if let value = row.value {
self.category.HiddenPreviewsBodyPlaceholder = value
}
Expand All @@ -193,9 +190,8 @@ class NotificationCategoryConfigurator: HAFormViewController, TypedRowController
} else {
$0.value = L10n.NotificationsConfigurator.Category.Rows.CategorySummary.default
}
}.onChange { row in
// swiftlint:disable:next force_try
try! self.realm.write {
}.onChange { [realm] row in
realm.reentrantWrite {
if let value = row.value {
self.category.CategorySummaryFormat = value
}
Expand Down Expand Up @@ -260,8 +256,7 @@ class NotificationCategoryConfigurator: HAFormViewController, TypedRowController
if let index = indexes.first?.section, let section = form.allSections[index] as? MultivaluedSection {
let deletedIDs = rows.compactMap(\.tag)

// swiftlint:disable:next force_try
try! realm.write {
realm.reentrantWrite {
// if the category isn't persisted yet, we need to remove the actions manually
category.Actions.remove(
atOffsets: category.Actions
Expand Down Expand Up @@ -319,7 +314,7 @@ class NotificationCategoryConfigurator: HAFormViewController, TypedRowController

row.presentationMode = PresentationMode.show(controllerProvider: ControllerProvider.callback { [category] in
NotificationActionConfigurator(category: category, action: action)
}, onDismiss: { vc in
}, onDismiss: { [realm, weak self] vc in
vc.navigationController?.popViewController(animated: true)

if let vc = vc as? NotificationActionConfigurator {
Expand All @@ -330,8 +325,8 @@ class NotificationCategoryConfigurator: HAFormViewController, TypedRowController
vc.row.updateCell()
Current.Log.verbose("action \(vc.action)")

// swiftlint:disable:next force_try
try! self.realm.write {
realm.reentrantWrite {
guard let self = self else { return }
// only add into realm if the category is also persisted
self.category.realm?.add(vc.action, update: .all)

Expand All @@ -340,7 +335,7 @@ class NotificationCategoryConfigurator: HAFormViewController, TypedRowController
}
}

self.updatePreview()
self?.updatePreview()
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,7 @@ class NotificationCategoryListViewController: HAFormViewController {
Current.Log.verbose("Saving category! \(vc.category)")

let realm = Current.realm()

// swiftlint:disable:next force_try
try! realm.write {
realm.reentrantWrite {
realm.add(vc.category, update: .all)
}
}
Expand All @@ -128,8 +126,7 @@ class NotificationCategoryListViewController: HAFormViewController {
let realm = Current.realm()

if (rows.first as? ButtonRowWithPresent<NotificationCategoryConfigurator>) != nil {
// swiftlint:disable:next force_try
try! realm.write {
realm.reentrantWrite {
realm.delete(realm.objects(NotificationCategory.self).filter("Identifier IN %@", deletedIDs))
}
}
Expand Down
24 changes: 7 additions & 17 deletions Sources/App/Settings/SettingsDetailViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -538,8 +538,7 @@ class SettingsDetailViewController: HAFormViewController, TypedRowControllerType

if (rows.first as? ButtonRowWithPresent<ActionConfigurator>) != nil {
Current.Log.verbose("Removed row is ActionConfiguration \(deletedIDs)")
// swiftlint:disable:next force_try
try! realm.write {
realm.reentrantWrite {
realm.delete(realm.objects(Action.self).filter("ID IN %@", deletedIDs))
}
}
Expand Down Expand Up @@ -576,12 +575,8 @@ class SettingsDetailViewController: HAFormViewController, TypedRowControllerType
_ = vc.navigationController?.popViewController(animated: true)

if let vc = vc as? ActionConfigurator, vc.shouldSave, let realm = rlmScene.realm {
do {
try realm.write {
realm.add(vc.action, update: .all)
}
} catch {
Current.Log.error("Error while saving to Realm!: \(error)")
realm.reentrantWrite {
realm.add(vc.action, update: .all)
}
}
})
Expand Down Expand Up @@ -661,16 +656,11 @@ class SettingsDetailViewController: HAFormViewController, TypedRowControllerType
Current.Log.verbose("Saving action! \(vc.action)")

let realm = Current.realm()

do {
try realm.write {
realm.add(vc.action, update: .all)
}

realm.reentrantWrite {
realm.add(vc.action, update: .all)
}.done {
self?.updatePositions()
} catch let error as NSError {
Current.Log.error("Error while saving to Realm!: \(error)")
}
}.cauterize()
}
})
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/App/ZoneManager/ZoneManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class ZoneManager {
// ^ not tap for this side effect because we don't want to do this on failure
guard let self = self else { return }
self.sync(zones: AnyCollection(self.zones))
}.done {
}.then {
Current.clientEventStore.addEvent(ClientEvent(
text: "Updated location",
type: .locationUpdate,
Expand All @@ -118,7 +118,7 @@ class ZoneManager {
text: "Didn't update: \(error.localizedDescription)",
type: .locationUpdate,
payload: updatedPayload
))
)).cauterize()
}
}

Expand Down Expand Up @@ -161,7 +161,7 @@ class ZoneManager {
payload: [
"region": String(describing: region),
]
))
)).cauterize()
locationManager.stopMonitoring(for: region)
}

Expand All @@ -172,7 +172,7 @@ class ZoneManager {
payload: [
"region": String(describing: region),
]
))
)).cauterize()

collector.ignoreNextState(for: region)
locationManager.startMonitoring(for: region)
Expand Down
3 changes: 0 additions & 3 deletions Sources/App/ZoneManager/ZoneManagerIgnoreReason.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ enum ZoneManagerIgnoreReason: LocalizedError, Equatable {
case unknownRegion
case zoneDisabled
case ignoredSSID(String)
case zoneUpdateFailed(NSError) // NSError so Equatable for laziness
case beaconExitIgnored
case recentlyUpdated

Expand All @@ -28,8 +27,6 @@ enum ZoneManagerIgnoreReason: LocalizedError, Equatable {
return "zone has tracking disabled"
case let .ignoredSSID(ssid):
return "ignored due to ssid \(ssid)"
case let .zoneUpdateFailed(error):
return "failed to update realm: \(error.localizedDescription)"
case .beaconExitIgnored:
return "beacon exit ignored"
case .recentlyUpdated:
Expand Down
8 changes: 2 additions & 6 deletions Sources/App/ZoneManager/ZoneManagerProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,8 @@ class ZoneManagerProcessorImpl: ZoneManagerProcessor {
return ignore(.ignoredSSID(current))
}

do {
try zone.realm?.reentrantWrite {
zone.inRegion = state == .inside
}
} catch {
return ignore(.zoneUpdateFailed(error as NSError))
zone.realm?.reentrantWrite {
zone.inRegion = state == .inside
}

if region is CLBeaconRegion, state == .outside {
Expand Down
2 changes: 1 addition & 1 deletion Sources/App/ZoneManager/ZoneManagerRegionFilter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,6 @@ class ZoneManagerRegionFilterImpl: ZoneManagerRegionFilter {
"stripped_zones": strippedZones.map(\.ID),
"stripped_decision": decisionSource,
]
))
)).cauterize()
}
}
4 changes: 2 additions & 2 deletions Sources/Extensions/Watch/ExtensionDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class ExtensionDelegate: NSObject, WKExtensionDelegate {

Current.Log.verbose("Updating actions from context \(actions)")

try? realm.write {
realm.reentrantWrite {
realm.delete(realm.objects(Action.self))
realm.add(actions, update: .all)
}
Expand All @@ -203,7 +203,7 @@ class ExtensionDelegate: NSObject, WKExtensionDelegate {

Current.Log.verbose("Updating complications from context \(complications)")

try? realm.write {
realm.reentrantWrite {
realm.delete(realm.objects(WatchComplication.self))
realm.add(complications, update: .all)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Shared/API/Authentication/TokenManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public class TokenManager {
"error": String(describing: underlying),
]
)
Current.clientEventStore.addEvent(event)
Current.clientEventStore.addEvent(event).cauterize()

self.tokenInfo = nil
Current.settingsStore.tokenInfo = nil
Expand Down
Loading

0 comments on commit 7cbde6d

Please sign in to comment.