diff --git a/core/database/src/androidMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt b/core/database/src/androidMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt index 8e9fbbac2..e5e97fcfb 100644 --- a/core/database/src/androidMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt +++ b/core/database/src/androidMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt @@ -45,7 +45,7 @@ actual fun getDatabaseBuilder(dbName: String): RoomDatabase.Builder = Room.inMemoryDatabaseBuilder(factory = { MeshtasticDatabaseConstructor.initialize() }) - .configureCommon() + .configureCommon(multiConnection = false) .setDriver(BundledSQLiteDriver()) /** Returns the Android directory where database files are stored. */ diff --git a/core/database/src/commonMain/kotlin/org/meshtastic/core/database/MeshtasticDatabase.kt b/core/database/src/commonMain/kotlin/org/meshtastic/core/database/MeshtasticDatabase.kt index bea88198d..4baa33afb 100644 --- a/core/database/src/commonMain/kotlin/org/meshtastic/core/database/MeshtasticDatabase.kt +++ b/core/database/src/commonMain/kotlin/org/meshtastic/core/database/MeshtasticDatabase.kt @@ -139,11 +139,20 @@ abstract class MeshtasticDatabase : RoomDatabase() { abstract fun discoveryDao(): DiscoveryDao companion object { - /** Configures a [RoomDatabase.Builder] with standard settings for this project. */ - fun RoomDatabase.Builder.configureCommon(): RoomDatabase.Builder = - this.fallbackToDestructiveMigration(dropAllTables = false) - .setMultipleConnectionPool(maxNumOfReaders = 4, maxNumOfWriters = 1) - .setQueryCoroutineContext(ioDispatcher) + /** + * Configures a [RoomDatabase.Builder] with standard settings for this project. + * + * @param multiConnection opens a multi-reader connection pool for concurrent reads. Production/file databases + * want this. In-memory databases (tests) MUST pass `false`: a pooled reader connection can serve a snapshot + * older than the latest write on the writer connection, so a read immediately after a write may observe stale + * rows — making read-after-write assertions non-deterministically flaky (see `DeviceLinkRepositoryImplTest`). + * A single connection serializes reads behind writes. + */ + fun RoomDatabase.Builder.configureCommon( + multiConnection: Boolean = true, + ): RoomDatabase.Builder = this.fallbackToDestructiveMigration(dropAllTables = false) + .apply { if (multiConnection) setMultipleConnectionPool(maxNumOfReaders = 4, maxNumOfWriters = 1) } + .setQueryCoroutineContext(ioDispatcher) } } diff --git a/core/database/src/iosMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt b/core/database/src/iosMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt index 459c024ea..6cecf57f1 100644 --- a/core/database/src/iosMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt +++ b/core/database/src/iosMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt @@ -51,7 +51,7 @@ actual fun getDatabaseBuilder(dbName: String): RoomDatabase.Builder = Room.inMemoryDatabaseBuilder(factory = { MeshtasticDatabaseConstructor.initialize() }) - .configureCommon() + .configureCommon(multiConnection = false) .setDriver(BundledSQLiteDriver()) /** Returns the iOS directory where database files are stored. */ diff --git a/core/database/src/jvmMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt b/core/database/src/jvmMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt index 9686529d7..50e84898d 100644 --- a/core/database/src/jvmMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt +++ b/core/database/src/jvmMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt @@ -57,7 +57,7 @@ actual fun getDatabaseBuilder(dbName: String): RoomDatabase.Builder = Room.inMemoryDatabaseBuilder(factory = { MeshtasticDatabaseConstructor.initialize() }) - .configureCommon() + .configureCommon(multiConnection = false) .setDriver(BundledSQLiteDriver()) /** Returns the JVM/Desktop directory where database files are stored. */