Prevent race creating + clean up sensor entries for old/deleted servers (#4386)

- Prevent a race on logout from the frontend between updating the sensors and deleting the server data, causing stale sensor entries
 - During periodic sensor updates, clean up any orphaned sensor entries there might be (because of this bug or other race conditions we're unaware of)
This commit is contained in:
Joris Pelgröm 2024-05-06 17:15:29 +02:00 committed by GitHub
parent fef2670c2b
commit 395b553772
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 4 deletions

View file

@ -208,6 +208,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
private var mFilePathCallback: ValueCallback<Array<Uri>>? = null
private var isConnected = false
private var isShowingError = false
private var isRelaunching = false
private var alertDialog: AlertDialog? = null
private var isVideoFullScreen = false
private var videoHeight = 0
@ -708,8 +709,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
@JavascriptInterface
fun revokeExternalAuth(callback: String) {
presenter.onRevokeExternalAuth(JSONObject(callback).get("callback") as String)
relaunchApp()
finish()
isRelaunching = true // Prevent auth errors from showing
}
@JavascriptInterface
@ -913,7 +913,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
override fun onPause() {
super.onPause()
presenter.setAppActive(false)
if (!isFinishing) SensorReceiver.updateAllSensors(this)
if (!isFinishing && !isRelaunching) SensorReceiver.updateAllSensors(this)
}
private suspend fun checkAndWarnForDisabledLocation() {
@ -1219,6 +1219,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
}
override fun relaunchApp() {
isRelaunching = true
startActivity(Intent(this, LaunchActivity::class.java))
finish()
}
@ -1284,7 +1285,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
error: SslError?,
description: String?
) {
if (isShowingError || !isStarted) {
if (isShowingError || !isStarted || isRelaunching) {
return
}
isShowingError = true

View file

@ -66,6 +66,18 @@ abstract class SensorWorkerBase(
}
sensorReceiver.updateSensors(appContext, serverManager, sensorDao, null)
}
// Cleanup orphaned sensors that may have been created by a slow or long running update
// writing data when deleting the server.
val currentServerIds = serverManager.defaultServers.map { it.id }
val orphanedSensors = sensorDao.getAllExceptServer(currentServerIds)
if (orphanedSensors.any()) {
Log.i(TAG, "Cleaning up ${orphanedSensors.size} orphaned sensor entries")
orphanedSensors.forEach {
sensorDao.removeSensor(it.id, it.serverId)
}
}
Result.success()
}

View file

@ -38,6 +38,9 @@ interface SensorDao {
@Query("SELECT * FROM Sensors WHERE server_id = :serverId")
suspend fun getAllServer(serverId: Int): List<Sensor>
@Query("SELECT * FROM Sensors WHERE NOT(server_id IN (:serverIds))")
suspend fun getAllExceptServer(serverIds: List<Int>): List<Sensor>
@Transaction
@Query("SELECT * FROM sensor_settings WHERE sensor_id = :id")
fun getSettings(id: String): List<SensorSetting>