mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1923364 - Add topic guides for app-services, r=nanj,markh DONTBUILD
Bug 1923364 - cleanup extensions, r=nanj Bug 1923364 - Adding tabs to lint, r=nanj Bug 1923364 - Ignore tabs linting, r=nanj Bug 1923364 - Restructure and combine rust components, r=nanj Bug 1923364 - Replace rst with MyST markdown, r=nanj Bug 1923364 - PR review fixes, r=nanj Differential Revision: https://phabricator.services.mozilla.com/D224949
This commit is contained in:
parent
280ba92800
commit
b7941358f4
@ -39,6 +39,7 @@ categories:
|
|||||||
- accessible
|
- accessible
|
||||||
- code-quality
|
- code-quality
|
||||||
- writing-rust-code
|
- writing-rust-code
|
||||||
|
- rust-components
|
||||||
- tools/profiler
|
- tools/profiler
|
||||||
- performance
|
- performance
|
||||||
- storage
|
- storage
|
||||||
|
10
docs/rust-components/index.md
Normal file
10
docs/rust-components/index.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Rust Components
|
||||||
|
|
||||||
|
This section is meant to make it easier to use and implement cross-platform components written in Rust.
|
||||||
|
|
||||||
|
```{toctree}
|
||||||
|
:titlesonly:
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
Topic Guides <topic-guides/index>
|
||||||
|
uniffi
|
10
docs/rust-components/topic-guides/index.md
Normal file
10
docs/rust-components/topic-guides/index.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Topic Guides
|
||||||
|
|
||||||
|
Here are the guides on various topics related to Rust components.
|
||||||
|
|
||||||
|
```{toctree}
|
||||||
|
:titlesonly:
|
||||||
|
:maxdepth: 1
|
||||||
|
:glob:
|
||||||
|
|
||||||
|
*
|
69
docs/rust-components/topic-guides/relevancy.md
Normal file
69
docs/rust-components/topic-guides/relevancy.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
myst:
|
||||||
|
enable_extensions: ["colon_fence"]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Relevancy
|
||||||
|
|
||||||
|
The `relevancy` component tracks the user's interests locally, without sharing any data over the network. The component currently supports building an interest vector based on the URLs they visit.
|
||||||
|
|
||||||
|
## Setting up the store
|
||||||
|
|
||||||
|
To use the `RelevancyStore` in either Kotlin or Swift, you need to import the relevant classes and data types from the `MozillaAppServices` library.
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
import mozilla.appservices.relevancy.RelevancyStore
|
||||||
|
import mozilla.appservices.relevancy.InterestVector
|
||||||
|
|
||||||
|
val store = RelevancyStore(dbPath)
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
import MozillaAppServices
|
||||||
|
|
||||||
|
let store = RelevancyStore(dbPath: "path/to/database")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
To work with the RelevancyStore, you need to create an instance using a database path where the user’s interest data will be stored:
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
```kotlin
|
||||||
|
val store = RelevancyStore(dbPath)
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
let store = RelevancyStore(dbPath: "path/to/database")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
|
* `dbPath`: This is the path to the SQLite database where the relevancy data is stored. The initialization is non-blocking, and the database is opened lazily.
|
||||||
|
|
||||||
|
## Ingesting relevancy data
|
||||||
|
|
||||||
|
To build the user's interest vector, call the `ingest` function with a list of URLs ranked by frequency. This method downloads the interest data, classifies the user's top URLs, and builds the interest vector. This process may take time and should only be called from a worker thread.
|
||||||
|
|
||||||
|
### Example usage of `ingest`:
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
```kotlin
|
||||||
|
val topUrlsByFrequency = listOf("https://example.com", "https://another-example.com")
|
||||||
|
val interestVector = store.ingest(topUrlsByFrequency)
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
let topUrlsByFrequency = ["https://example.com", "https://another-example.com"]
|
||||||
|
let interestVector = store.ingest(topUrlsByFrequency)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
* `topUrlsByFrequency`: A list of URLs ranked by how often and recently the user has visited them. This data is used to build the user's interest vector.
|
||||||
|
* The `ingest` function returns an `InterestVector`, which contains the user's interest levels for different tracked categories.
|
165
docs/rust-components/topic-guides/suggest.md
Normal file
165
docs/rust-components/topic-guides/suggest.md
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
---
|
||||||
|
myst:
|
||||||
|
enable_extensions: ["colon_fence"]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Suggest
|
||||||
|
|
||||||
|
The API for the `SuggestStore` can be found in the [MozillaComponents Kotlin documentation](https://mozilla.github.io/application-services/kotlin/kotlin-components-docs/mozilla.appservices.suggest/-suggest-store/index.html).
|
||||||
|
|
||||||
|
```{note}
|
||||||
|
Make sure you initialize {doc}`viaduct` for this component.
|
||||||
|
```
|
||||||
|
|
||||||
|
```{warning}
|
||||||
|
The `SuggestStore` is synchronous, which means it needs to be wrapped in the asynchronous primitive of the target language you are using.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Setting up the store
|
||||||
|
|
||||||
|
You need to import one or more of the following primitives to work with the `SuggestStore` (these come from the generated `suggest.kt` file, produced by `uniffi`):
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
import mozilla.appservices.remotesettings.RemoteSettingsServer
|
||||||
|
import mozilla.appservices.suggest.SuggestApiException
|
||||||
|
import mozilla.appservices.suggest.SuggestIngestionConstraints
|
||||||
|
import mozilla.appservices.suggest.SuggestStore
|
||||||
|
import mozilla.appservices.suggest.SuggestStoreBuilder
|
||||||
|
import mozilla.appservices.suggest.Suggestion
|
||||||
|
import mozilla.appservices.suggest.SuggestionQuery
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
import MozillaAppServices
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
Create a `SuggestStore` as a singleton. You do this via the `SuggestStoreBuilder`, which returns a `SuggestStore`. No I/O or network requests are performed during construction, which makes this safe to do at any point in the application startup:
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
```kotlin
|
||||||
|
internal val store: SuggestStore = {
|
||||||
|
SuggestStoreBuilder()
|
||||||
|
.dataPath(context.getDatabasePath(DATABASE_NAME).absolutePath)
|
||||||
|
.remoteSettingsServer(remoteSettingsServer)
|
||||||
|
.build()
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
let store: SuggestStore = {
|
||||||
|
let storeBuilder = SuggestStoreBuilder()
|
||||||
|
storeBuilder.dataPath(context.getDatabasePath(DATABASE_NAME).absolutePath)
|
||||||
|
storeBuilder.remoteSettingsServer(remoteSettingsServer)
|
||||||
|
return storeBuilder.build()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
* You need to set the `dataPath`, which is the path (the SQLite location) where you store your suggestions.
|
||||||
|
* The `remoteSettingsServer` is only needed if you want to set the server to anything else but `prod`. If so, you pass a `RemoteSettingsServer` object.
|
||||||
|
|
||||||
|
## Ingesting suggestions
|
||||||
|
|
||||||
|
Ingesting suggestions happens in two different ways: On startup, and then, periodically, in the background.
|
||||||
|
|
||||||
|
* `SuggestIngestionConstraints` is used to control what gets ingested.
|
||||||
|
* Use the `providers` field to limit ingestion by provider type.
|
||||||
|
* Use the `providerConstraints` field to add additional constraints, currently this is only used for exposure suggestions.
|
||||||
|
|
||||||
|
### On Start Up
|
||||||
|
|
||||||
|
Ingest with `SuggestIngestionConstraints(emptyOnly=true)` shortly after each startup. This ensures we have something in the DB on the first run and also after upgrades where we often will clear the DB to start from scratch.
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
```kotlin
|
||||||
|
store.value.ingest(SuggestIngestionConstraints(
|
||||||
|
emptyOnly = true,
|
||||||
|
providers = listOf(SuggestionProvider.AMP_MOBILE, SuggestionProvider.WIKIPEDIA, SuggestionProvider.WEATHER)
|
||||||
|
))
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
store.value.ingest(SuggestIngestionConstraints(
|
||||||
|
emptyOnly: true,
|
||||||
|
providers: [.AMP_MOBILE, .WIKIPEDIA, .WEATHER]
|
||||||
|
))
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Periodically
|
||||||
|
|
||||||
|
Ingest with `SuggestIngestionConstraints(emptyOnly=false)` on a regular schedule (like once a day).
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
```kotlin
|
||||||
|
store.value.ingest(SuggestIngestionConstraints(emptyOnly = false))
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
store.value.ingest(SuggestIngestionConstraints(emptyOnly: false))
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Querying Suggestions
|
||||||
|
|
||||||
|
Call `SuggestStore::query` to fetch suggestions for the suggest bar. The `providers` parameter should be the same value that got passed to `ingest()`.
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
```kotlin
|
||||||
|
store.value.query(
|
||||||
|
SuggestionQuery(
|
||||||
|
keyword = text,
|
||||||
|
providers = listOf(SuggestionProvider.AMP_MOBILE, SuggestionProvider.WIKIPEDIA, SuggestionProvider.WEATHER),
|
||||||
|
limit = MAX_NUM_OF_FIREFOX_SUGGESTIONS,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
store.value.query(
|
||||||
|
SuggestionQuery(
|
||||||
|
keyword: text,
|
||||||
|
providers: [.AMP_MOBILE, .WIKIPEDIA, .WEATHER],
|
||||||
|
limit: MAX_NUM_OF_FIREFOX_SUGGESTIONS
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Interrupt querying
|
||||||
|
|
||||||
|
Call `SuggestStore::Interrupt` with `InterruptKind::Read` to interrupt any in-progress queries when the user cancels a query and before running the next query.
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
```kotlin
|
||||||
|
store.value.interrupt()
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
store.value.interrupt()
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Shutdown the store
|
||||||
|
|
||||||
|
On shutdown, call `SuggestStore::Interrupt` with `InterruptKind::ReadWrite` to interrupt any in-progress ingestion and queries.
|
||||||
|
|
||||||
|
:::{tab-set-code}
|
||||||
|
:sync-group: language
|
||||||
|
```kotlin
|
||||||
|
store.value.interrupt()
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift
|
||||||
|
store.value.interrupt()
|
||||||
|
```
|
||||||
|
:::
|
9
docs/rust-components/topic-guides/viaduct.md
Normal file
9
docs/rust-components/topic-guides/viaduct.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Viaduct
|
||||||
|
|
||||||
|
`Viaduct` initialization is required for all platforms and for multiple components. The [README](https://github.com/mozilla/application-services/blob/main/components/viaduct/README.md) explains the component in more detail.
|
||||||
|
|
||||||
|
There are 3 different options to use `viaduct`:
|
||||||
|
|
||||||
|
* Any `libxul` based can ignore initialization, since it's handled by `libxul`.
|
||||||
|
* Using the reqwest backend, which uses the `reqwest` library and a `reqwest`-managed thread.
|
||||||
|
* Implementing the C FFI like `libxul` does (https://searchfox.org/mozilla-central/source/toolkit/components/viaduct).
|
@ -197,6 +197,8 @@ SPHINX_TREES["testing-rust-code"] = "docs/testing-rust-code"
|
|||||||
|
|
||||||
SPHINX_TREES["writing-rust-code"] = "docs/writing-rust-code"
|
SPHINX_TREES["writing-rust-code"] = "docs/writing-rust-code"
|
||||||
|
|
||||||
|
SPHINX_TREES["rust-components"] = "docs/rust-components"
|
||||||
|
|
||||||
SPHINX_TREES["bug-mgmt"] = "docs/bug-mgmt"
|
SPHINX_TREES["bug-mgmt"] = "docs/bug-mgmt"
|
||||||
|
|
||||||
SPHINX_TREES["glossary"] = "docs/glossary"
|
SPHINX_TREES["glossary"] = "docs/glossary"
|
||||||
|
@ -9,6 +9,7 @@ pypi:myst-parser==2.0
|
|||||||
pypi:sphinx-copybutton==0.5.2
|
pypi:sphinx-copybutton==0.5.2
|
||||||
pypi:sphinx-design==0.5.0
|
pypi:sphinx-design==0.5.0
|
||||||
pypi:sphinx-js==3.2.2
|
pypi:sphinx-js==3.2.2
|
||||||
|
pypi:sphinx-tabs==3.4.7
|
||||||
pypi:sphinx-markdown-tables==0.0.17
|
pypi:sphinx-markdown-tables==0.0.17
|
||||||
pypi:sphinx-rtd-theme==2.0.0
|
pypi:sphinx-rtd-theme==2.0.0
|
||||||
pypi:sphinxcontrib-mermaid==0.9.2
|
pypi:sphinxcontrib-mermaid==0.9.2
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# This file is autogenerated by pip-compile with Python 3.11
|
# This file is autogenerated by pip-compile with Python 3.12
|
||||||
# by the following command:
|
# by the following command:
|
||||||
#
|
#
|
||||||
# pip-compile --generate-hashes --output-file=tools/lint/rst/requirements.txt ./tools/lint/rst/requirements.in
|
# pip-compile --generate-hashes --output-file=tools/lint/rst/requirements.txt ./tools/lint/rst/requirements.in
|
||||||
|
Loading…
Reference in New Issue
Block a user