Skip to content

Conversation

@subsymbolic
Copy link
Contributor

@subsymbolic subsymbolic commented Jul 27, 2018

Task/Issue URL: https://app.asana.com/0/72649045549333/721626625236432
Tech Design URL: https://app.asana.com/0/72649045549333/727813825116580

Description:
Add large scale https support to android

  • Removes legacy https solution
  • Adds updated https solution
  • Adds new api requests
  • Clear old https data and perform database migration to support new format

Steps to test this PR:

TEST ONE:

  1. Visit the http://wikipedia.org
  2. Check the logs and ensure they report that this site is "upgradable"
  3. Note that the scheme is updated to https

TEST TWO:

  1. Visit the http://aaaaaaaaaaaaa.co.uk
  2. Check the logs and ensure they report that this site is not "upgradable"
  3. Note that the scheme remains as "http"
  4. The site itself doesn't exist (thus definitely not in our upgrade list), so won't load

TEST THREE:

  1. Install the app from develop and run it
  2. Then install this version over the top
  3. Ensure that the db migration succeeds and nothing goes boom!

Internal references:

Software Engineering Expectations
Technical Design Template

@subsymbolic
Copy link
Contributor Author

Note Bitrise is struggling with the cpp submodule so I am regenerating the CI job to better support submodules. See https://devcenter.bitrise.io/faq/adding-projects-with-submodules/ or more information about the issue.

@subsymbolic subsymbolic force-pushed the feature/large_scale_https_upgrades branch from 121f1e5 to 4741a65 Compare July 27, 2018 17:45
* Remove old component and replace with new
* Download https data, validate and persist
* Add migration including deleting old records
* Unit tests
Also move other 3rd party libs into correct folder
@subsymbolic subsymbolic force-pushed the feature/large_scale_https_upgrades branch from 4741a65 to 832c700 Compare July 27, 2018 17:49
@subsymbolic subsymbolic changed the title Large scale https upgrades - WIP Large scale https upgrades Aug 10, 2018
@subsymbolic subsymbolic requested a review from CDRussell August 10, 2018 21:10
@subsymbolic
Copy link
Contributor Author

Bitrise Update: The Bitrise submodule issue was fixed by using the github https (rather than ssh) url for the submodule.

val md = MessageDigest.getInstance("SHA-256")
md.reset()
val digest = md.digest(this)
return String.format("%0" + digest.size * 2 + "x", BigInteger(1, digest))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this doing more manual string concatenation than necessary? Or is there a reason why digest.size *2 isn't provided as a param?

Copy link
Contributor Author

@subsymbolic subsymbolic Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm generating the format specifier there (not the string itself). I'm open to alternatives.

System.loadLibrary("https-bloom-lib")
}

constructor(maxItems: Int, targetProbability: Double) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mark this as @VisibleForTesting if it's not needed from production code?

Copy link
Contributor Author

@subsymbolic subsymbolic Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is an appropriate part of the API for this class, matching the C++ code. I don't feel a need to hide it but am happy to if you feel strongly about it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just because it's in the C++ code, does that mean we need to have it exposed in Kotlin? If yes, then happy to leave it.

But if not, it seems we only call it from testing and it might not exist otherwise, hence why I was thinking that annotation might help explain its existence.

But i don't feel strongly about it.

return true
}
httpsBloomFilter?.let {
val shouldUpgrade = it.contains(uri.host)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should assign uri.host to a local variable in case it's in any way expensive to parse out the host from the Uri (and we use it twice in quick succession)


override fun create(): BloomFilter? {

val specificationWrapper = Observable.just(dao)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed IRL, maybe we need to get this off the main thread.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great feedback @CDRussell. I've made this update but used a Rx io Scheduler (not thread {}) to allow for testing

import javax.inject.Inject

interface HttpsBloomFilterFactory {
fun create(): BloomFilter?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to other comment about threading, does this need to be asynchronous so work can be avoided on the main thread? or if it's to be called on a worker thread, should we annotate it as such?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely! Thanks :)

if (response.isSuccessful) {
val whitelist = response.body()!!
Timber.d("Updating https whitelist with new data")
whitelistDao.deleteAll()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make a method on the Dao which both deletes and inserts, so that we can mark it with @Transaction to ensure the deletion and insertion both either happen or neither happens?

fun count(): Int
fun insert(specification: HttpsBloomFilterSpec)

@Query("select * from https_bloom_filter_spec limit 1")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uppercase the SQL keywords?

Copy link
Contributor Author

@subsymbolic subsymbolic Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a pattern we currently use in our codebase (nearly all the DAOs are lowercase). How do you feel about discussing the convention in our next FDRI meeting and then updating the code universally according to the decision we make?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right; we use a mishmash of upper and lower case, even in the same query 😞

Cool, ignore it for this PR

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(domains: List<HttpsWhitelistedDomain>)

@Query("select count(1) > 0 from https_whitelisted_domain where domain = :domain")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uppercase keywords?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my previous comment.

- avd-manager@0.9.2: {}
- avd-manager@0.9.2:
inputs:
- version: '27'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@CDRussell
Copy link
Member

CDRussell commented Aug 15, 2018

I see an issue when upgrading from develop. This looks related to this Room issue: https://issuetracker.google.com/issues/79362399.

The app is left in a broken state from here it seems, but restarting the app resolves the issue. It isn't clear if the migration steps succeeded or failed as a result.

Updating to Room 1.1.1 seems to remove the issue. Though it's an increase in scope for your task, I think we might need to do that as part of this PR.

Thoughts @subsymbolic ?

08-15 10:21:29.228 29305-29330/com.duckduckgo.mobile.android E/ROOM: Invalidation tracker is initialized twice :/. 08-15 10:21:29.234 29305-29342/com.duckduckgo.mobile.android W/zygote: Long monitor contention with owner RxCachedThreadScheduler-1 (29330) at int android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(long, long)(SQLiteConnection.java:-2) waiters=3 in android.arch.persistence.db.SupportSQLiteDatabase android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase() for 305ms 08-15 10:21:29.302 29305-29343/com.duckduckgo.mobile.android E/ROOM: Cannot run invalidation tracker. Is the db closed? java.lang.IllegalStateException: The database '/data/user/0/com.duckduckgo.mobile.android/databases/app.db' is not open. at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2262) at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:394) at android.database.sqlite.SQLiteDatabase.-android_database_sqlite_SQLiteDatabase-mthref-0(SQLiteDatabase.java:95) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.$m$0(Unknown Source:4) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.get(Unknown Source:0) at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180) at java.lang.ThreadLocal.get(ThreadLocal.java:170) at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:388) at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101) at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45) at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) 08-15 10:21:29.564 29305-29362/com.duckduckgo.mobile.android W/cr_ChildProcLH: Create a new ChildConnectionAllocator with package name = com.android.chrome, sandboxed = true 08-15 10:21:29.604 29305-29305/com.duckduckgo.mobile.android W/.mobile.android: type=1400 audit(0.0:76): avc: denied { read } for name="vmstat" dev="proc" ino=4026532039 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=0 08-15 10:21:30.251 29305-29358/com.duckduckgo.mobile.android W/cr_CrashFileManager: /data/user/0/com.duckduckgo.mobile.android/cache/WebView/Crash Reports does not exist or is not a directory 08-15 10:21:31.921 29305-29343/com.duckduckgo.mobile.android E/ROOM: Cannot run invalidation tracker. Is the db closed? java.lang.IllegalStateException: The database '/data/user/0/com.duckduckgo.mobile.android/databases/app.db' is not open. at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2262) at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:394) at android.database.sqlite.SQLiteDatabase.-android_database_sqlite_SQLiteDatabase-mthref-0(SQLiteDatabase.java:95) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.$m$0(Unknown Source:4) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.get(Unknown Source:0) at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180) at java.lang.ThreadLocal.get(ThreadLocal.java:170) at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:388) at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101) at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45) at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) 08-15 10:21:31.975 29305-29342/com.duckduckgo.mobile.android E/ROOM: Cannot run invalidation tracker. Is the db closed? java.lang.IllegalStateException: The database '/data/user/0/com.duckduckgo.mobile.android/databases/app.db' is not open. at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2262) at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:394) at android.database.sqlite.SQLiteDatabase.-android_database_sqlite_SQLiteDatabase-mthref-0(SQLiteDatabase.java:95) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.$m$0(Unknown Source:4) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.get(Unknown Source:0) at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180) at java.lang.ThreadLocal.get(ThreadLocal.java:170) at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:388) at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101) at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45) at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) 08-15 10:21:32.047 29305-29333/com.duckduckgo.mobile.android E/SQLiteLog: (1) no such table: room_table_modification_log 08-15 10:21:32.048 29305-29333/com.duckduckgo.mobile.android W/DuckDuckGoApplication$configureDataDownloader: Failed to download initial app configuration no such table: room_table_modification_log (code 1): , while compiling: INSERT OR REPLACE INTO app_configuration(key,appConfigurationDownloaded) VALUES (?,?) 08-15 10:21:32.048 29305-29343/com.duckduckgo.mobile.android E/ROOM: Cannot run invalidation tracker. Is the db closed? java.lang.IllegalStateException: The database '/data/user/0/com.duckduckgo.mobile.android/databases/app.db' is not open. at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2262) at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:394) at android.database.sqlite.SQLiteDatabase.-android_database_sqlite_SQLiteDatabase-mthref-0(SQLiteDatabase.java:95) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.$m$0(Unknown Source:4) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.get(Unknown Source:0) at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180) at java.lang.ThreadLocal.get(ThreadLocal.java:170) at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:388) at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101) at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45) at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) 08-15 10:21:35.292 29305-29342/com.duckduckgo.mobile.android E/ROOM: Cannot run invalidation tracker. Is the db closed? java.lang.IllegalStateException: The database '/data/user/0/com.duckduckgo.mobile.android/databases/app.db' is not open. at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2262) at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:394) at android.database.sqlite.SQLiteDatabase.-android_database_sqlite_SQLiteDatabase-mthref-0(SQLiteDatabase.java:95) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.$m$0(Unknown Source:4) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.get(Unknown Source:0) at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180) at java.lang.ThreadLocal.get(ThreadLocal.java:170) at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:388) at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101) at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45) at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) 08-15 10:21:36.840 29305-29343/com.duckduckgo.mobile.android E/ROOM: Cannot run invalidation tracker. Is the db closed? java.lang.IllegalStateException: The database '/data/user/0/com.duckduckgo.mobile.android/databases/app.db' is not open. at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2262) at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:394) at android.database.sqlite.SQLiteDatabase.-android_database_sqlite_SQLiteDatabase-mthref-0(SQLiteDatabase.java:95) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.$m$0(Unknown Source:4) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.get(Unknown Source:0) at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180) at java.lang.ThreadLocal.get(ThreadLocal.java:170) at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:388) at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101) at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45) at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) 08-15 10:21:36.878 29305-29342/com.duckduckgo.mobile.android E/ROOM: Cannot run invalidation tracker. Is the db closed? java.lang.IllegalStateException: The database '/data/user/0/com.duckduckgo.mobile.android/databases/app.db' is not open. at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2262) at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:394) at android.database.sqlite.SQLiteDatabase.-android_database_sqlite_SQLiteDatabase-mthref-0(SQLiteDatabase.java:95) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.$m$0(Unknown Source:4) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.get(Unknown Source:0) at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180) at java.lang.ThreadLocal.get(ThreadLocal.java:170) at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:388) at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101) at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45) at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) 08-15 10:21:36.906 29305-29343/com.duckduckgo.mobile.android E/ROOM: Cannot run invalidation tracker. Is the db closed? java.lang.IllegalStateException: The database '/data/user/0/com.duckduckgo.mobile.android/databases/app.db' is not open. at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2262) at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:394) at android.database.sqlite.SQLiteDatabase.-android_database_sqlite_SQLiteDatabase-mthref-0(SQLiteDatabase.java:95) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.$m$0(Unknown Source:4) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.get(Unknown Source:0) at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180) at java.lang.ThreadLocal.get(ThreadLocal.java:170) at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:388) at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101) at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45) at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) 08-15 10:21:36.907 29305-29330/com.duckduckgo.mobile.android E/SQLiteLog: (1) no such table: room_table_modification_log 08-15 10:21:36.907 29305-29330/com.duckduckgo.mobile.android W/AppConfigurationJobService$onStartJob: Failed to download app configuration no such table: room_table_modification_log (code 1): , while compiling: INSERT OR REPLACE INTO app_configuration(key,appConfigurationDownloaded) VALUES (?,?) 08-15 10:21:36.907 29305-29330/com.duckduckgo.mobile.android W/AppConfigurationJobService: Error executing job 08-15 10:21:36.907 29305-29342/com.duckduckgo.mobile.android E/ROOM: Cannot run invalidation tracker. Is the db closed? java.lang.IllegalStateException: The database '/data/user/0/com.duckduckgo.mobile.android/databases/app.db' is not open. at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2262) at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:394) at android.database.sqlite.SQLiteDatabase.-android_database_sqlite_SQLiteDatabase-mthref-0(SQLiteDatabase.java:95) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.$m$0(Unknown Source:4) at android.database.sqlite.-$Lambda$gPaS7kMbZ8xtrrEx06GlwJ2iDWE.get(Unknown Source:0) at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284) at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180) at java.lang.ThreadLocal.get(ThreadLocal.java:170) at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:388) at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101) at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45) at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764)

val initialTime = System.nanoTime()
val shouldUpgrade = it.contains(host)
val totalTime = System.nanoTime() - initialTime
Timber.d("${host} ${if (shouldUpgrade) "is" else "is not"} upgradable, lookup in ${totalTime/NANO_TO_MILLIS_DIVISOR}ms")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it nicer to use TimeUnit here for the conversion rather than doing it manually?

TimeUnit.NANOSECONDS.toMillis(totalTime) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly not. TimeUnit conversions only return whole numbers, so would always spit out zero.

return null
}

val initialTimestamp = Date().time
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this isn't performance-critical code path, this probably doesn't matter but....

creating a new Date object here is more overhead than grabbing the System.currentTimeMillis() directly

in fact, the constructor of Date does just that anyway

public Date() {
    this(System.currentTimeMillis());
}

so we'd be better replacing Date().time with System.currentTimeMillis() I think.

@subsymbolic
Copy link
Contributor Author

Thanks for the review @CDRussell!

@subsymbolic subsymbolic merged commit e0469f4 into develop Aug 15, 2018
@subsymbolic subsymbolic deleted the feature/large_scale_https_upgrades branch August 15, 2018 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants