Skip to content

Commit

Permalink
Avoid updating database in background (#3436)
Browse files Browse the repository at this point in the history
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->

## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->

## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->

## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#

## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
  • Loading branch information
bgoncal authored Feb 17, 2025
1 parent 5d15417 commit 4cbae34
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 16 deletions.
4 changes: 0 additions & 4 deletions HomeAssistant.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,6 @@
421B1C182BD6524E001ED18C /* WidgetBuilderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421B1C172BD6524E001ED18C /* WidgetBuilderViewModel.swift */; };
421B1C1D2BD65C04001ED18C /* View+ConditionalModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421B1C1B2BD65BFA001ED18C /* View+ConditionalModifier.swift */; };
4221ED352D009EF700BAE3EB /* AppDatabaseUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4221ED332D009BD000BAE3EB /* AppDatabaseUpdater.swift */; };
4221ED362D009EF700BAE3EB /* AppDatabaseUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4221ED332D009BD000BAE3EB /* AppDatabaseUpdater.swift */; };
4223688B2D40F9B7005911E4 /* WidgetCustom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4223688A2D40F9B7005911E4 /* WidgetCustom.swift */; };
4223688E2D40FB00005911E4 /* WidgetCustomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4223688D2D40FB00005911E4 /* WidgetCustomTimelineProvider.swift */; };
422368902D40FCDE005911E4 /* CustomWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4223688F2D40FCDE005911E4 /* CustomWidget.swift */; };
Expand Down Expand Up @@ -835,7 +834,6 @@
42DD84162B14D7AC00936F16 /* WebViewExternalBusMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DD84142B14D68C00936F16 /* WebViewExternalBusMessage.swift */; };
42DD84192B14D83B00936F16 /* WebViewExternalBusMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DD84182B14D83B00936F16 /* WebViewExternalBusMessageTests.swift */; };
42DE75D32D1061A600FF379F /* PanelsUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DE75D12D105F3000FF379F /* PanelsUpdater.swift */; };
42DE75D42D1061A600FF379F /* PanelsUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DE75D12D105F3000FF379F /* PanelsUpdater.swift */; };
42DEDA9A2C5B926400E9D29D /* AppVersionSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DEDA992C5B926400E9D29D /* AppVersionSensor.swift */; };
42DEDA9B2C5B926400E9D29D /* AppVersionSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DEDA992C5B926400E9D29D /* AppVersionSensor.swift */; };
42DF6B2D2CCF8A2200D7EC14 /* PermissionRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DF6B2C2CCF8A2200D7EC14 /* PermissionRequestView.swift */; };
Expand Down Expand Up @@ -7375,7 +7373,6 @@
424151FD2CD8F27100D7A6F9 /* CarPlayConfig.swift in Sources */,
113A8D4A283C7B1700B9DA32 /* PeriodicUpdateManager.swift in Sources */,
4264906C2C0F1B60002155CC /* AssistChatItem.swift in Sources */,
4221ED362D009EF700BAE3EB /* AppDatabaseUpdater.swift in Sources */,
424151FA2CD8EF2200D7A6F9 /* MagicItem+Migration.swift in Sources */,
42070EED2BAC523F0031E96F /* AssistService.swift in Sources */,
B6872E642226841400C475D1 /* MobileAppRegistrationRequest.swift in Sources */,
Expand Down Expand Up @@ -7439,7 +7436,6 @@
11CFD78227364F450082D557 /* Identifier.swift in Sources */,
11AF4D17249C8083006C74C0 /* With.swift in Sources */,
42333ADB2D0B1771001E8408 /* EntityRegistryListForDisplay.swift in Sources */,
42DE75D42D1061A600FF379F /* PanelsUpdater.swift in Sources */,
11B38EF7275C54A300205C7B /* UpdateSensorsIntentHandler.swift in Sources */,
1141182B24AFA10900E6525C /* WebhookResponseHandler.swift in Sources */,
426266462C11B02C0081A818 /* InteractiveImmediateMessages.swift in Sources */,
Expand Down
9 changes: 7 additions & 2 deletions Sources/App/Scenes/WebViewSceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,13 @@ final class WebViewSceneDelegate: NSObject, UIWindowSceneDelegate {
Current.modelManager.subscribe(isAppInForeground: {
UIApplication.shared.applicationState == .active
})
Current.appDatabaseUpdater.update()
Current.panelsUpdater.update()

Current.appDatabaseUpdater.update {
UIApplication.shared.applicationState
}
Current.panelsUpdater.update {
UIApplication.shared.applicationState
}

let widgetsCacheFile = AppConstants.widgetsCacheURL

Expand Down
5 changes: 1 addition & 4 deletions Sources/App/Settings/SettingsRootDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ enum SettingsRootDataSource {
$0.icon = .watchVariantIcon
$0.hidden = .isCatalyst
$0.presentationMode = .presentModally(controllerProvider: ControllerProvider.callback {
Current.appDatabaseUpdater.update()
let controller = UIHostingController(rootView: WatchConfigurationView())
controller.overrideUserInterfaceStyle = .dark
return controller
Expand All @@ -175,7 +174,6 @@ enum SettingsRootDataSource {
$0.icon = .carBackIcon
$0.hidden = .isCatalyst
$0.presentationMode = .presentModally(controllerProvider: ControllerProvider.callback {
Current.appDatabaseUpdater.update()
let controller = UIHostingController(rootView: CarPlayConfigurationView())
controller.overrideUserInterfaceStyle = .dark
return controller
Expand Down Expand Up @@ -214,8 +212,7 @@ enum SettingsRootDataSource {
$0.title = L10n.Settings.Widgets.title
$0.icon = .widgetsIcon
$0.presentationMode = .show(controllerProvider: ControllerProvider.callback {
Current.appDatabaseUpdater.update()
return UIHostingController(rootView: WidgetBuilderView())
UIHostingController(rootView: WidgetBuilderView())
}, onDismiss: nil)
}
}
Expand Down
7 changes: 7 additions & 0 deletions Sources/App/Settings/SettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ class SettingsViewController: HAFormViewController {
<<< SettingsRootDataSource.Row.whatsNew.row
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Current.appDatabaseUpdater.update {
UIApplication.shared.applicationState
}
}

@objc func openAbout(_ sender: UIButton) {
let aboutView = AboutViewController()

Expand Down
8 changes: 5 additions & 3 deletions Sources/Shared/Environment/AppDatabaseUpdater.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import Foundation
import GRDB
import HAKit
import UIKit

public protocol AppDatabaseUpdaterProtocol {
func stop()
func update()
func update(uiApplicationState: @escaping () -> UIApplication.State)
}

final class AppDatabaseUpdater: AppDatabaseUpdaterProtocol {
Expand All @@ -17,7 +18,7 @@ final class AppDatabaseUpdater: AppDatabaseUpdaterProtocol {
cancelOnGoingRequests()
}

func update() {
func update(uiApplicationState: @escaping () -> UIApplication.State) {
cancelOnGoingRequests()

if let lastUpdate, lastUpdate.timeIntervalSinceNow > -5 {
Expand All @@ -30,13 +31,13 @@ final class AppDatabaseUpdater: AppDatabaseUpdaterProtocol {
Current.Log.verbose("Updating database, servers count \(Current.servers.all.count)")
Current.servers.all.forEach { server in
guard server.info.connection.activeURL() != nil else { return }

// Cache entities
let requestToken = Current.api(for: server)?.connection.send(
HATypedRequest<[HAEntity]>.fetchStates(),
completion: { result in
switch result {
case let .success(entities):
guard uiApplicationState() == .active else { return }
Current.appEntitiesModel().updateModel(Set(entities), server: server)
case let .failure(error):
Current.Log.error("Failed to fetch states: \(error)")
Expand All @@ -58,6 +59,7 @@ final class AppDatabaseUpdater: AppDatabaseUpdaterProtocol {
completion: { [weak self] result in
switch result {
case let .success(response):
guard uiApplicationState() == .active else { return }
self?.saveEntityRegistryListForDisplay(response, serverId: server.identifier.rawValue)
case let .failure(error):
Current.Log.error("Failed to fetch EntityRegistryListForDisplay: \(error)")
Expand Down
2 changes: 1 addition & 1 deletion Sources/Shared/Environment/Environment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ public class AppEnvironment {
AppEntitiesModel.shared
}

#if os(iOS)
public var appDatabaseUpdater: AppDatabaseUpdaterProtocol = AppDatabaseUpdater.shared

public var panelsUpdater: PanelsUpdaterProtocol = PanelsUpdater.shared

#if os(iOS)
public var realmFatalPresentation: ((UIViewController) -> Void)?
#endif

Expand Down
7 changes: 5 additions & 2 deletions Sources/Shared/Panels/PanelsUpdater.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import Foundation
import GRDB
import PromiseKit
import UIKit

public protocol PanelsUpdaterProtocol {
func update()
func update(uiApplicationState: () -> UIApplication.State)
}

final class PanelsUpdater: PanelsUpdaterProtocol {
Expand All @@ -12,7 +13,7 @@ final class PanelsUpdater: PanelsUpdaterProtocol {
private var tokens: [(promise: Promise<HAPanels>, cancel: () -> Void)?] = []
private var lastUpdate: Date?

public func update() {
public func update(uiApplicationState: () -> UIApplication.State) {
if let lastUpdate, lastUpdate.timeIntervalSinceNow > -5 {
Current.Log.verbose("Skipping panels update, last update was \(lastUpdate)")
return
Expand All @@ -26,6 +27,8 @@ final class PanelsUpdater: PanelsUpdaterProtocol {
for server in Current.servers.all {
let request = Current.api(for: server)?.connection.send(.panels())
tokens.append(request)

guard uiApplicationState() == .active else { return }
request?.promise.done({ [weak self] panels in
self?.saveInDatabase(panels, server: server)
}).cauterize()
Expand Down

0 comments on commit 4cbae34

Please sign in to comment.