Skip to content

Commit

Permalink
Switch suggest component from UDL to proc-macros
Browse files Browse the repository at this point in the history
  • Loading branch information
gruberb committed Sep 18, 2024
1 parent 8be45cd commit 38330cd
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 268 deletions.
7 changes: 0 additions & 7 deletions components/suggest/build.rs

This file was deleted.

4 changes: 2 additions & 2 deletions components/suggest/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use crate::rs::{DownloadedGlobalConfig, DownloadedWeatherData};

/// Global Suggest configuration data.
#[derive(Clone, Default, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[derive(Clone, Default, Debug, Deserialize, Serialize, PartialEq, Eq, uniffi::Record)]
pub struct SuggestGlobalConfig {
pub show_less_frequently_cap: i32,
}
Expand All @@ -22,7 +22,7 @@ impl From<&DownloadedGlobalConfig> for SuggestGlobalConfig {
}

/// Per-provider configuration data.
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, uniffi::Enum)]
pub enum SuggestProviderConfig {
Weather { min_keyword_length: i32 },
}
Expand Down
6 changes: 3 additions & 3 deletions components/suggest/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ pub impl<T> Result<T, rusqlite::Error> {

/// The error type for all Suggest component operations. These errors are
/// exposed to your application, which should handle them as needed.
#[derive(Debug, thiserror::Error)]
#[derive(Debug, thiserror::Error, uniffi::Error)]
#[non_exhaustive]
pub enum SuggestApiError {
#[error("Network error: {reason}")]
Network { reason: String },
// The server requested a backoff after too many requests
/// The server requested a backoff after too many requests
#[error("Backoff")]
Backoff { seconds: u64 },
// The application interrupted a request
/// An operation was interrupted by calling `SuggestStore.interrupt()`
#[error("Interrupted")]
Interrupted,
#[error("Other error: {reason}")]
Expand Down
10 changes: 6 additions & 4 deletions components/suggest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ mod testing;
mod yelp;

pub use config::{SuggestGlobalConfig, SuggestProviderConfig};
pub use error::SuggestApiError;
pub use error::{Error, SuggestApiError};
pub use metrics::{LabeledTimingSample, SuggestIngestionMetrics};
pub use provider::{SuggestionProvider, SuggestionProviderConstraints};
pub use query::{QueryWithMetricsResult, SuggestionQuery};
pub use store::{InterruptKind, SuggestIngestionConstraints, SuggestStore, SuggestStoreBuilder};
pub use suggestion::{raw_suggestion_url_matches, Suggestion};

pub(crate) type Result<T> = std::result::Result<T, error::Error>;
pub type SuggestApiResult<T> = std::result::Result<T, error::SuggestApiError>;
pub(crate) type Result<T> = std::result::Result<T, Error>;
pub type SuggestApiResult<T> = std::result::Result<T, SuggestApiError>;

uniffi::include_scaffolding!("suggest");
uniffi::use_udl_record!(remote_settings, RemoteSettingsConfig);
uniffi::use_udl_enum!(remote_settings, RemoteSettingsServer);
uniffi::setup_scaffolding!();
8 changes: 6 additions & 2 deletions components/suggest/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
use std::time::Instant;

/// Single sample for a Glean labeled_timing_distribution
#[derive(uniffi::Record)]
pub struct LabeledTimingSample {
pub label: String,
pub value: u64, // time in microseconds
/// Time in microseconds
pub value: u64,
}

impl LabeledTimingSample {
Expand All @@ -19,9 +21,11 @@ impl LabeledTimingSample {
/// Ingestion metrics
///
/// These are recorded during [crate::Store::ingest] and returned to the consumer to record.
#[derive(Default)]
#[derive(Default, uniffi::Record)]
pub struct SuggestIngestionMetrics {
/// Samples for the `suggest.ingestion_time` metric
pub ingestion_times: Vec<LabeledTimingSample>,
/// Samples for the `suggest.ingestion_download_time` metric
pub download_times: Vec<LabeledTimingSample>,
}

Expand Down
9 changes: 7 additions & 2 deletions components/suggest/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub(crate) const DEFAULT_INGEST_PROVIDERS: [SuggestionProvider; 6] = [
];

/// A provider is a source of search suggestions.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, uniffi::Enum)]
#[repr(u8)]
pub enum SuggestionProvider {
Amp = 1,
Expand Down Expand Up @@ -121,7 +121,12 @@ impl ToSql for SuggestionProvider {
}
}

#[derive(Clone, Default, Debug)]
/// Some providers manage multiple suggestion subtypes. Queries, ingests, and
/// other operations on those providers must be constrained to a desired subtype.
#[derive(Clone, Default, Debug, uniffi::Record)]
pub struct SuggestionProviderConstraints {
/// `Exposure` provider - For each desired exposure suggestion type, this
/// should contain the value of the `suggestion_type` field of its remote
/// settings record(s).
pub exposure_suggestion_types: Option<Vec<String>>,
}
4 changes: 3 additions & 1 deletion components/suggest/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
use crate::{LabeledTimingSample, Suggestion, SuggestionProvider, SuggestionProviderConstraints};

/// A query for suggestions to show in the address bar.
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, uniffi::Record)]
pub struct SuggestionQuery {
pub keyword: String,
pub providers: Vec<SuggestionProvider>,
pub provider_constraints: Option<SuggestionProviderConstraints>,
pub limit: Option<i32>,
}

#[derive(uniffi::Record)]
pub struct QueryWithMetricsResult {
pub suggestions: Vec<Suggestion>,
/// Samples for the `suggest.query_time` metric
pub query_times: Vec<LabeledTimingSample>,
}

Expand Down
24 changes: 22 additions & 2 deletions components/suggest/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use crate::{
///
/// Using a builder is preferred to calling the constructor directly since it's harder to confuse
/// the data_path and cache_path strings.
#[derive(uniffi::Object)]
pub struct SuggestStoreBuilder(Mutex<SuggestStoreBuilderInner>);

#[derive(Default)]
Expand All @@ -50,7 +51,9 @@ impl Default for SuggestStoreBuilder {
}
}

#[uniffi::export]
impl SuggestStoreBuilder {
#[uniffi::constructor]
pub fn new() -> SuggestStoreBuilder {
Self(Mutex::new(SuggestStoreBuilderInner::default()))
}
Expand All @@ -60,6 +63,7 @@ impl SuggestStoreBuilder {
self
}

/// Deprecated: this is no longer used by the suggest component.
pub fn cache_path(self: Arc<Self>, _path: String) -> Arc<Self> {
// We used to use this, but we're not using it anymore, just ignore the call
self
Expand All @@ -75,6 +79,11 @@ impl SuggestStoreBuilder {
self
}

/// Add an sqlite3 extension to load
///
/// library_name should be the name of the library without any extension, for example `libmozsqlite3`.
/// entrypoint should be the entry point, for example `sqlite3_fts5_init`. If `null` (the default)
/// entry point will be used (see https://sqlite.org/loadext.html for details).
pub fn load_extension(
self: Arc<Self>,
library: String,
Expand Down Expand Up @@ -109,7 +118,7 @@ impl SuggestStoreBuilder {
}

/// What should be interrupted when [SuggestStore::interrupt] is called?
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, uniffi::Enum)]
pub enum InterruptKind {
/// Interrupt read operations like [SuggestStore::query]
Read,
Expand Down Expand Up @@ -148,13 +157,16 @@ pub enum InterruptKind {
/// to request a small subset of the Suggest data and download the rest
/// later, while a desktop on a fast link might download the entire dataset
/// on the first launch.
#[derive(uniffi::Object)]
pub struct SuggestStore {
inner: SuggestStoreInner<RemoteSettingsClient>,
}

#[uniffi::export]
impl SuggestStore {
/// Creates a Suggest store.
#[handle_error(Error)]
#[uniffi::constructor]
pub fn new(
path: &str,
settings_config: Option<RemoteSettingsConfig>,
Expand Down Expand Up @@ -245,18 +257,26 @@ impl SuggestStore {
) -> SuggestApiResult<Option<SuggestProviderConfig>> {
self.inner.fetch_provider_config(provider)
}
}

impl SuggestStore {
pub fn force_reingest(&self) {
self.inner.force_reingest()
}
}

/// Constraints limit which suggestions to ingest from Remote Settings.
#[derive(Clone, Default, Debug)]
#[derive(Clone, Default, Debug, uniffi::Record)]
pub struct SuggestIngestionConstraints {
pub providers: Option<Vec<SuggestionProvider>>,
pub provider_constraints: Option<SuggestionProviderConstraints>,
/// Only run ingestion if the table `suggestions` is empty
///
// This is indented to handle periodic updates. Consumers can schedule an ingest with
// `empty_only=true` on startup and a regular ingest with `empty_only=false` to run on a long periodic schedule (maybe
// once a day). This allows ingestion to normally be run at a slow, periodic rate. However, if
// there is a schema upgrade that causes the database to be thrown away, then the
// `empty_only=true` ingestion that runs on startup will repopulate it.
pub empty_only: bool,
}

Expand Down
Loading

0 comments on commit 38330cd

Please sign in to comment.