-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix bad queries after adding new propreties to entity list #6402
Conversation
This should prevent issues with reset() being called while another transaction is running or a thread has a reference to a writable/ readable database.
I'm not able to reproduce the issue #6396 (error doesn't occur) and I haven't found any errors connected with adding properties in Central so it seems that it's fixed |
body: SQLiteDatabase.() -> T | ||
) { | ||
transaction(body) | ||
databaseConnection.reset() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd been unable to write a Robolectric test that would drive out adding this reset()
with the existing implementation. I'm guessing that it may have been possible to write one in an instrumentation test.
However, now if you remove reset()
, a few tests fail in the existing DatabaseEntitiesRepository
. This is because the change to looking up columns to determine which to add (using ALTER TABLE
) is much more sensitive to the problem than the previous implementation that used a try-catch
to just "fire and forget" add columns. I'm leaning towards not bothering with a new instrumentation test as it feels unlikely that anyone would go back to the old hacky implementation, but happy to debate that!
db/src/main/java/org/odk/collect/db/sqlite/SynchronizedDatabaseConnection.kt
Show resolved
Hide resolved
...ct_app/src/main/java/org/odk/collect/android/database/entities/DatabaseEntitiesRepository.kt
Outdated
Show resolved
Hide resolved
db/src/main/java/org/odk/collect/db/sqlite/DatabaseConnection.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are still some occurrences of writeable
in DatabaseFormsRepository
please fix them as well.
aeb4f0c
to
a154665
Compare
Tested with Success! Verified on a device with Android 10 Verified Cases:
|
Tested with Success Verified on device with Android 14 |
Closes #6396
Why is this the best possible solution? Were any other approaches considered?
As per the discussion in #6396, the conclusion was eventually made that the root cause was due to
ALTER TABLE
statements being executed in a shared database connection (SqlLiteOpenHelper
). The solution here is to reset that connection (using a newDatabaseConnetion#reset
method) so that follow-up queries do not end up getting incorrect/state data or data structures.I've also added a new
SynchronizedDatabaseConnection
class that allows us to interact withDatabaseConnection
in a synchornized way to stop prevent any problems that might come up from concurrent access combined withreset()
. The reason for this is described in a comment onreset()
:Using synchornized access for
DatabaseConnection
inDatabaseEntitiesRepository
will theoretically have performance implications as two threads will not be able to simultaneously read from the DB. To some level this was already not possible (asSqlLiteOpenHelper
serializes calls to the actual underlying database), but it will certainly expand the amount of "blocking" code. The real world impact for entities is basically non-existent as we're planning to remove concurrent form entry/form updates anyway in #6232 which would be the only situation that would benefit as far as I can tell. I think adding this lower level protection is important to reduce the risk of adding race conditions down the road.How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?
This should just fix the bug. Checking entity form downloads and form entry would be good here as this is a fairly low level change that could always have unforeseen consequences.
Before submitting this PR, please make sure you have:
./gradlew connectedAndroidTest
(or./gradlew testLab
) and confirmed all checks still passDateFormatsTest