Commit 6896e440 authored by MozLando's avatar MozLando
Browse files

Merge #6396



6396: Closes #6394 - Add warm-up API to places and logins storage layers r=jonalmeida a=grigoryk

This allows consumers to ensure that underlying database connections are fully established.
After `warmUp` is called, there should be no additional overhead upon first access to the storage.
Co-authored-by: default avatarGrisha Kruglov <gkruglov@mozilla.com>
parents 0ac4adeb ace5ccd4
......@@ -30,6 +30,10 @@ class InMemoryHistoryStorage : HistoryStorage {
@VisibleForTesting
internal val pageMeta: HashMap<String, PageObservation> = hashMapOf()
override suspend fun warmUp() {
// No-op for an in-memory store
}
override suspend fun recordVisit(uri: String, visit: PageVisit) {
val now = System.currentTimeMillis()
if (visit.redirectSource != RedirectSource.NOT_A_SOURCE) {
......
......@@ -19,6 +19,7 @@ import mozilla.components.concept.storage.Storage
import mozilla.components.concept.sync.SyncStatus
import mozilla.components.concept.sync.SyncableStore
import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.utils.logElapsedTime
/**
* A base class for concrete implementations of PlacesStorages
......@@ -39,6 +40,13 @@ abstract class PlacesStorage(context: Context) : Storage, SyncableStore {
internal val writer: PlacesWriterConnection by lazy { places.writer() }
internal val reader: PlacesReaderConnection by lazy { places.reader() }
override suspend fun warmUp() {
logElapsedTime(logger, "Warming up places storage") {
writer
reader
}
}
/**
* Internal database maintenance tasks. Ideally this should be called once a day.
*/
......
......@@ -17,6 +17,7 @@ import mozilla.appservices.remotetabs.RemoteTabsProvider
import mozilla.appservices.remotetabs.SyncAuthInfo as RustSyncAuthInfo
import mozilla.components.concept.sync.SyncAuthInfo
import mozilla.components.concept.sync.SyncStatus
import mozilla.components.support.utils.logElapsedTime
/**
* An interface which defines read/write methods for remote tabs data.
......@@ -24,7 +25,11 @@ import mozilla.components.concept.sync.SyncStatus
open class RemoteTabsStorage : Storage, SyncableStore {
internal val api by lazy { RemoteTabsProvider() }
private val scope by lazy { CoroutineScope(Dispatchers.IO) }
internal val logger = Logger("PlacesHistoryStorage")
internal val logger = Logger("RemoteTabsStorage")
override suspend fun warmUp() {
logElapsedTime(logger, "Warming up storage") { api }
}
/**
* Store the locally opened tabs.
......
......@@ -8,6 +8,10 @@ package mozilla.components.concept.storage
* An interface which provides generic operations for storing browser data like history and bookmarks.
*/
interface Storage {
/**
* Make sure underlying database connections are established.
*/
suspend fun warmUp()
/**
* Runs internal database maintenance tasks
......
......@@ -115,6 +115,10 @@ class BookmarksStorageSuggestionProviderTest {
class testableBookmarksStorage : BookmarksStorage {
val bookmarkMap: HashMap<String, BookmarkNode> = hashMapOf()
override suspend fun warmUp() {
throw NotImplementedError()
}
override suspend fun getTree(guid: String, recursive: Boolean): BookmarkNode? {
// "Not needed for the test"
throw NotImplementedError()
......
......@@ -63,6 +63,10 @@ class HistoryDelegateTest {
var getVisitedListCalled = false
var getVisitedPlainCalled = false
override suspend fun warmUp() {
fail()
}
override suspend fun recordVisit(uri: String, visit: PageVisit) {
fail()
}
......
......@@ -42,6 +42,7 @@ dependencies {
implementation project(':concept-storage')
implementation project(':support-sync-telemetry')
implementation project(':support-utils')
implementation project(':service-glean')
implementation Dependencies.kotlin_stdlib
......
......@@ -15,7 +15,9 @@ import mozilla.appservices.sync15.SyncTelemetryPing
import mozilla.components.concept.storage.Login
import mozilla.components.concept.storage.LoginsStorage
import mozilla.components.concept.sync.SyncableStore
import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.sync.telemetry.SyncTelemetry
import mozilla.components.support.utils.logElapsedTime
import org.json.JSONObject
import java.io.Closeable
......@@ -113,6 +115,7 @@ class SyncableLoginsStorage(
private val context: Context,
private val key: String
) : LoginsStorage, SyncableStore, AutoCloseable {
private val logger = Logger("SyncableLoginsStorage")
private val coroutineContext by lazy { Dispatchers.IO }
private val conn by lazy {
......@@ -120,6 +123,14 @@ class SyncableLoginsStorage(
LoginStorageConnection
}
/**
* "Warms up" this storage layer by establishing the database connection.
*/
suspend fun warmUp() = withContext(coroutineContext) {
logElapsedTime(logger, "Warming up storage") { conn }
Unit
}
/**
* @throws [LoginsStorageException] if the storage is locked, and on unexpected
* errors (IO failure, rust panics, etc)
......
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package mozilla.components.support.utils
import mozilla.components.support.base.log.logger.Logger
/**
* Executes the given [block] and logs the elapsed time in milliseconds.
* Uses [System.nanoTime] for measurements, since it isn't tied to a wall-clock.
*
* @param logger [Logger] to use for logging.
* @param op Name of the operation [block] performs.
* @param block A lambda to measure.
* @return [T] result of running [block].
*/
@SuppressWarnings("MagicNumber")
inline fun <T> logElapsedTime(logger: Logger, op: String, block: () -> T): T {
logger.info("$op...")
val start = System.nanoTime()
val res = block()
logger.info("'$op' took ${(System.nanoTime() - start) / 1_000_000} ms")
return res
}
......@@ -24,6 +24,9 @@ permalink: /changelog/
* **support-migration**
* ⚠️ **This is a breaking change**: `FennecMigrator` now takes `Lazy` references to storage layers.
* **concept-storage**, **service-sync-logins**
* 🆕 New API: `PlacesStorage#warmUp`, `SyncableLoginsStorage#warmUp` - allows consumers to ensure that underlying storage database connections are fully established.
# 37.0.0
* [Commits](https://github.com/mozilla-mobile/android-components/compare/v36.0.0...v37.0.0)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment