feat(analytics): Integrate Datadog for RUM and Logging (#2578)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich 2025-08-01 16:54:46 -05:00 committed by GitHub
parent f5478b42c3
commit ab22a655c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 348 additions and 194 deletions

View file

@ -27,7 +27,9 @@ import kotlinx.coroutines.withContext
import java.io.IOException
import javax.inject.Inject
class DeviceHardwareRepository @Inject constructor(
class DeviceHardwareRepository
@Inject
constructor(
private val apiDataSource: DeviceHardwareRemoteDataSource,
private val localDataSource: DeviceHardwareLocalDataSource,
private val jsonDataSource: DeviceHardwareJsonDataSource,
@ -45,15 +47,13 @@ class DeviceHardwareRepository @Inject constructor(
} else {
val cachedHardware = localDataSource.getByHwModel(hwModel)
if (cachedHardware != null && !isCacheExpired(cachedHardware.lastUpdated)) {
debug("Using recent cached device hardware")
val externalModel = cachedHardware.asExternalModel()
return@withContext externalModel
}
}
try {
debug("Fetching device hardware from server")
val deviceHardware = apiDataSource.getAllDeviceHardware()
?: throw IOException("empty response from server")
val deviceHardware =
apiDataSource.getAllDeviceHardware() ?: throw IOException("empty response from server")
localDataSource.insertAllDeviceHardware(deviceHardware)
val cachedHardware = localDataSource.getByHwModel(hwModel)
val externalModel = cachedHardware?.asExternalModel()
@ -65,7 +65,6 @@ class DeviceHardwareRepository @Inject constructor(
debug("Using stale cached device hardware")
return@withContext cachedHardware.asExternalModel()
}
debug("Loading and caching device hardware from local JSON asset")
localDataSource.insertAllDeviceHardware(jsonDataSource.loadDeviceHardwareFromJsonAsset())
cachedHardware = localDataSource.getByHwModel(hwModel)
val externalModel = cachedHardware?.asExternalModel()
@ -78,10 +77,7 @@ class DeviceHardwareRepository @Inject constructor(
localDataSource.deleteAllDeviceHardware()
}
/**
* Check if the cache is expired
*/
private fun isCacheExpired(lastUpdated: Long): Boolean {
return System.currentTimeMillis() - lastUpdated > CACHE_EXPIRATION_TIME_MS
}
/** Check if the cache is expired */
private fun isCacheExpired(lastUpdated: Long): Boolean =
System.currentTimeMillis() - lastUpdated > CACHE_EXPIRATION_TIME_MS
}

View file

@ -17,7 +17,6 @@
package com.geeksville.mesh.repository.api
import com.geeksville.mesh.android.BuildUtils.debug
import com.geeksville.mesh.android.BuildUtils.warn
import com.geeksville.mesh.database.entity.FirmwareRelease
import com.geeksville.mesh.database.entity.FirmwareReleaseType
@ -28,7 +27,9 @@ import kotlinx.coroutines.flow.flow
import java.io.IOException
import javax.inject.Inject
class FirmwareReleaseRepository @Inject constructor(
class FirmwareReleaseRepository
@Inject
constructor(
private val apiDataSource: FirmwareReleaseRemoteDataSource,
private val localDataSource: FirmwareReleaseLocalDataSource,
private val jsonDataSource: FirmwareReleaseJsonDataSource,
@ -43,61 +44,50 @@ class FirmwareReleaseRepository @Inject constructor(
val alphaRelease: Flow<FirmwareRelease?> = getLatestFirmware(FirmwareReleaseType.ALPHA)
private fun getLatestFirmware(
releaseType: FirmwareReleaseType,
refresh: Boolean = false
): Flow<FirmwareRelease?> = flow {
if (refresh) {
invalidateCache()
} else {
val cachedRelease = localDataSource.getLatestRelease(releaseType)
if (cachedRelease != null && !isCacheExpired(cachedRelease.lastUpdated)) {
debug("Using recent cached firmware release")
val externalModel = cachedRelease.asExternalModel()
private fun getLatestFirmware(releaseType: FirmwareReleaseType, refresh: Boolean = false): Flow<FirmwareRelease?> =
flow {
if (refresh) {
invalidateCache()
} else {
val cachedRelease = localDataSource.getLatestRelease(releaseType)
if (cachedRelease != null && !isCacheExpired(cachedRelease.lastUpdated)) {
val externalModel = cachedRelease.asExternalModel()
emit(externalModel)
return@flow
}
}
try {
val networkFirmwareReleases =
apiDataSource.getFirmwareReleases() ?: throw IOException("empty response from server")
val releases =
when (releaseType) {
FirmwareReleaseType.STABLE -> networkFirmwareReleases.releases.stable
FirmwareReleaseType.ALPHA -> networkFirmwareReleases.releases.alpha
}
localDataSource.insertFirmwareReleases(releases, releaseType)
val cachedRelease = localDataSource.getLatestRelease(releaseType)
val externalModel = cachedRelease?.asExternalModel()
emit(externalModel)
} catch (e: IOException) {
warn("Failed to fetch firmware releases from server: ${e.message}")
val jsonFirmwareReleases = jsonDataSource.loadFirmwareReleaseFromJsonAsset()
val releases =
when (releaseType) {
FirmwareReleaseType.STABLE -> jsonFirmwareReleases.releases.stable
FirmwareReleaseType.ALPHA -> jsonFirmwareReleases.releases.alpha
}
localDataSource.insertFirmwareReleases(releases, releaseType)
val cachedRelease = localDataSource.getLatestRelease(releaseType)
val externalModel = cachedRelease?.asExternalModel()
emit(externalModel)
return@flow
}
}
try {
debug("Fetching firmware releases from server")
val networkFirmwareReleases = apiDataSource.getFirmwareReleases()
?: throw IOException("empty response from server")
val releases = when (releaseType) {
FirmwareReleaseType.STABLE -> networkFirmwareReleases.releases.stable
FirmwareReleaseType.ALPHA -> networkFirmwareReleases.releases.alpha
}
localDataSource.insertFirmwareReleases(
releases,
releaseType
)
val cachedRelease = localDataSource.getLatestRelease(releaseType)
val externalModel = cachedRelease?.asExternalModel()
emit(externalModel)
} catch (e: IOException) {
warn("Failed to fetch firmware releases from server: ${e.message}")
val jsonFirmwareReleases = jsonDataSource.loadFirmwareReleaseFromJsonAsset()
val releases = when (releaseType) {
FirmwareReleaseType.STABLE -> jsonFirmwareReleases.releases.stable
FirmwareReleaseType.ALPHA -> jsonFirmwareReleases.releases.alpha
}
localDataSource.insertFirmwareReleases(
releases,
releaseType
)
val cachedRelease = localDataSource.getLatestRelease(releaseType)
val externalModel = cachedRelease?.asExternalModel()
emit(externalModel)
}
}
suspend fun invalidateCache() {
localDataSource.deleteAllFirmwareReleases()
}
/**
* Check if the cache is expired
*/
private fun isCacheExpired(lastUpdated: Long): Boolean {
return System.currentTimeMillis() - lastUpdated > CACHE_EXPIRATION_TIME_MS
}
/** Check if the cache is expired */
private fun isCacheExpired(lastUpdated: Long): Boolean =
System.currentTimeMillis() - lastUpdated > CACHE_EXPIRATION_TIME_MS
}