Add telemetry events for loading extensions (#9793)
* Store extensions versions' wasm API version in the database * Share a common struct for extension API responses between collab and client * Add wasm API version and schema version to extension API responses Release Notes: - N/A Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
parent
9b62e461ed
commit
5adc51f113
22 changed files with 531 additions and 306 deletions
|
@ -1,3 +1,5 @@
|
|||
use chrono::Utc;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl Database {
|
||||
|
@ -31,22 +33,8 @@ impl Database {
|
|||
|
||||
Ok(extensions
|
||||
.into_iter()
|
||||
.filter_map(|(extension, latest_version)| {
|
||||
let version = latest_version?;
|
||||
Some(ExtensionMetadata {
|
||||
id: extension.external_id,
|
||||
name: extension.name,
|
||||
version: version.version,
|
||||
authors: version
|
||||
.authors
|
||||
.split(',')
|
||||
.map(|author| author.trim().to_string())
|
||||
.collect::<Vec<_>>(),
|
||||
description: version.description,
|
||||
repository: version.repository,
|
||||
published_at: version.published_at,
|
||||
download_count: extension.total_download_count as u64,
|
||||
})
|
||||
.filter_map(|(extension, version)| {
|
||||
Some(metadata_from_extension_and_version(extension, version?))
|
||||
})
|
||||
.collect())
|
||||
})
|
||||
|
@ -67,22 +55,29 @@ impl Database {
|
|||
.one(&*tx)
|
||||
.await?;
|
||||
|
||||
Ok(extension.and_then(|(extension, latest_version)| {
|
||||
let version = latest_version?;
|
||||
Some(ExtensionMetadata {
|
||||
id: extension.external_id,
|
||||
name: extension.name,
|
||||
version: version.version,
|
||||
authors: version
|
||||
.authors
|
||||
.split(',')
|
||||
.map(|author| author.trim().to_string())
|
||||
.collect::<Vec<_>>(),
|
||||
description: version.description,
|
||||
repository: version.repository,
|
||||
published_at: version.published_at,
|
||||
download_count: extension.total_download_count as u64,
|
||||
})
|
||||
Ok(extension.and_then(|(extension, version)| {
|
||||
Some(metadata_from_extension_and_version(extension, version?))
|
||||
}))
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_extension_version(
|
||||
&self,
|
||||
extension_id: &str,
|
||||
version: &str,
|
||||
) -> Result<Option<ExtensionMetadata>> {
|
||||
self.transaction(|tx| async move {
|
||||
let extension = extension::Entity::find()
|
||||
.filter(extension::Column::ExternalId.eq(extension_id))
|
||||
.filter(extension_version::Column::Version.eq(version))
|
||||
.inner_join(extension_version::Entity)
|
||||
.select_also(extension_version::Entity)
|
||||
.one(&*tx)
|
||||
.await?;
|
||||
|
||||
Ok(extension.and_then(|(extension, version)| {
|
||||
Some(metadata_from_extension_and_version(extension, version?))
|
||||
}))
|
||||
})
|
||||
.await
|
||||
|
@ -172,6 +167,7 @@ impl Database {
|
|||
repository: ActiveValue::Set(version.repository.clone()),
|
||||
description: ActiveValue::Set(version.description.clone()),
|
||||
schema_version: ActiveValue::Set(version.schema_version),
|
||||
wasm_api_version: ActiveValue::Set(version.wasm_api_version.clone()),
|
||||
download_count: ActiveValue::NotSet,
|
||||
}
|
||||
}))
|
||||
|
@ -241,3 +237,35 @@ impl Database {
|
|||
.await
|
||||
}
|
||||
}
|
||||
|
||||
fn metadata_from_extension_and_version(
|
||||
extension: extension::Model,
|
||||
version: extension_version::Model,
|
||||
) -> ExtensionMetadata {
|
||||
ExtensionMetadata {
|
||||
id: extension.external_id,
|
||||
manifest: rpc::ExtensionApiManifest {
|
||||
name: extension.name,
|
||||
version: version.version,
|
||||
authors: version
|
||||
.authors
|
||||
.split(',')
|
||||
.map(|author| author.trim().to_string())
|
||||
.collect::<Vec<_>>(),
|
||||
description: Some(version.description),
|
||||
repository: version.repository,
|
||||
schema_version: Some(version.schema_version),
|
||||
wasm_api_version: version.wasm_api_version,
|
||||
},
|
||||
|
||||
published_at: convert_time_to_chrono(version.published_at),
|
||||
download_count: extension.total_download_count as u64,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn convert_time_to_chrono(time: time::PrimitiveDateTime) -> chrono::DateTime<Utc> {
|
||||
chrono::DateTime::from_naive_utc_and_offset(
|
||||
chrono::NaiveDateTime::from_timestamp_opt(time.assume_utc().unix_timestamp(), 0).unwrap(),
|
||||
Utc,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ pub struct Model {
|
|||
pub repository: String,
|
||||
pub description: String,
|
||||
pub schema_version: i32,
|
||||
pub wasm_api_version: Option<String>,
|
||||
pub download_count: i64,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use super::Database;
|
||||
use crate::{
|
||||
db::{ExtensionMetadata, NewExtensionVersion},
|
||||
db::{queries::extensions::convert_time_to_chrono, ExtensionMetadata, NewExtensionVersion},
|
||||
test_both_dbs,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use time::{OffsetDateTime, PrimitiveDateTime};
|
||||
|
||||
test_both_dbs!(
|
||||
test_extensions,
|
||||
|
@ -19,8 +18,10 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
let extensions = db.get_extensions(None, 1, 5).await.unwrap();
|
||||
assert!(extensions.is_empty());
|
||||
|
||||
let t0 = OffsetDateTime::from_unix_timestamp_nanos(0).unwrap();
|
||||
let t0 = PrimitiveDateTime::new(t0.date(), t0.time());
|
||||
let t0 = time::OffsetDateTime::from_unix_timestamp_nanos(0).unwrap();
|
||||
let t0 = time::PrimitiveDateTime::new(t0.date(), t0.time());
|
||||
|
||||
let t0_chrono = convert_time_to_chrono(t0);
|
||||
|
||||
db.insert_extension_versions(
|
||||
&[
|
||||
|
@ -34,6 +35,7 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
authors: vec!["max".into()],
|
||||
repository: "ext1/repo".into(),
|
||||
schema_version: 1,
|
||||
wasm_api_version: None,
|
||||
published_at: t0,
|
||||
},
|
||||
NewExtensionVersion {
|
||||
|
@ -43,6 +45,7 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
authors: vec!["max".into(), "marshall".into()],
|
||||
repository: "ext1/repo".into(),
|
||||
schema_version: 1,
|
||||
wasm_api_version: None,
|
||||
published_at: t0,
|
||||
},
|
||||
],
|
||||
|
@ -56,6 +59,7 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
authors: vec!["marshall".into()],
|
||||
repository: "ext2/repo".into(),
|
||||
schema_version: 0,
|
||||
wasm_api_version: None,
|
||||
published_at: t0,
|
||||
}],
|
||||
),
|
||||
|
@ -84,22 +88,30 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
&[
|
||||
ExtensionMetadata {
|
||||
id: "ext1".into(),
|
||||
name: "Extension One".into(),
|
||||
version: "0.0.2".into(),
|
||||
authors: vec!["max".into(), "marshall".into()],
|
||||
description: "a good extension".into(),
|
||||
repository: "ext1/repo".into(),
|
||||
published_at: t0,
|
||||
manifest: rpc::ExtensionApiManifest {
|
||||
name: "Extension One".into(),
|
||||
version: "0.0.2".into(),
|
||||
authors: vec!["max".into(), "marshall".into()],
|
||||
description: Some("a good extension".into()),
|
||||
repository: "ext1/repo".into(),
|
||||
schema_version: Some(1),
|
||||
wasm_api_version: None,
|
||||
},
|
||||
published_at: t0_chrono,
|
||||
download_count: 0,
|
||||
},
|
||||
ExtensionMetadata {
|
||||
id: "ext2".into(),
|
||||
name: "Extension Two".into(),
|
||||
version: "0.2.0".into(),
|
||||
authors: vec!["marshall".into()],
|
||||
description: "a great extension".into(),
|
||||
repository: "ext2/repo".into(),
|
||||
published_at: t0,
|
||||
manifest: rpc::ExtensionApiManifest {
|
||||
name: "Extension Two".into(),
|
||||
version: "0.2.0".into(),
|
||||
authors: vec!["marshall".into()],
|
||||
description: Some("a great extension".into()),
|
||||
repository: "ext2/repo".into(),
|
||||
schema_version: Some(0),
|
||||
wasm_api_version: None,
|
||||
},
|
||||
published_at: t0_chrono,
|
||||
download_count: 0
|
||||
},
|
||||
]
|
||||
|
@ -111,12 +123,16 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
extensions,
|
||||
&[ExtensionMetadata {
|
||||
id: "ext2".into(),
|
||||
name: "Extension Two".into(),
|
||||
version: "0.2.0".into(),
|
||||
authors: vec!["marshall".into()],
|
||||
description: "a great extension".into(),
|
||||
repository: "ext2/repo".into(),
|
||||
published_at: t0,
|
||||
manifest: rpc::ExtensionApiManifest {
|
||||
name: "Extension Two".into(),
|
||||
version: "0.2.0".into(),
|
||||
authors: vec!["marshall".into()],
|
||||
description: Some("a great extension".into()),
|
||||
repository: "ext2/repo".into(),
|
||||
schema_version: Some(0),
|
||||
wasm_api_version: None,
|
||||
},
|
||||
published_at: t0_chrono,
|
||||
download_count: 0
|
||||
},]
|
||||
);
|
||||
|
@ -147,22 +163,30 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
&[
|
||||
ExtensionMetadata {
|
||||
id: "ext2".into(),
|
||||
name: "Extension Two".into(),
|
||||
version: "0.2.0".into(),
|
||||
authors: vec!["marshall".into()],
|
||||
description: "a great extension".into(),
|
||||
repository: "ext2/repo".into(),
|
||||
published_at: t0,
|
||||
manifest: rpc::ExtensionApiManifest {
|
||||
name: "Extension Two".into(),
|
||||
version: "0.2.0".into(),
|
||||
authors: vec!["marshall".into()],
|
||||
description: Some("a great extension".into()),
|
||||
repository: "ext2/repo".into(),
|
||||
schema_version: Some(0),
|
||||
wasm_api_version: None,
|
||||
},
|
||||
published_at: t0_chrono,
|
||||
download_count: 7
|
||||
},
|
||||
ExtensionMetadata {
|
||||
id: "ext1".into(),
|
||||
name: "Extension One".into(),
|
||||
version: "0.0.2".into(),
|
||||
authors: vec!["max".into(), "marshall".into()],
|
||||
description: "a good extension".into(),
|
||||
repository: "ext1/repo".into(),
|
||||
published_at: t0,
|
||||
manifest: rpc::ExtensionApiManifest {
|
||||
name: "Extension One".into(),
|
||||
version: "0.0.2".into(),
|
||||
authors: vec!["max".into(), "marshall".into()],
|
||||
description: Some("a good extension".into()),
|
||||
repository: "ext1/repo".into(),
|
||||
schema_version: Some(1),
|
||||
wasm_api_version: None,
|
||||
},
|
||||
published_at: t0_chrono,
|
||||
download_count: 5,
|
||||
},
|
||||
]
|
||||
|
@ -181,6 +205,7 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
authors: vec!["max".into(), "marshall".into()],
|
||||
repository: "ext1/repo".into(),
|
||||
schema_version: 1,
|
||||
wasm_api_version: None,
|
||||
published_at: t0,
|
||||
}],
|
||||
),
|
||||
|
@ -193,6 +218,7 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
authors: vec!["marshall".into()],
|
||||
repository: "ext2/repo".into(),
|
||||
schema_version: 0,
|
||||
wasm_api_version: None,
|
||||
published_at: t0,
|
||||
}],
|
||||
),
|
||||
|
@ -223,22 +249,30 @@ async fn test_extensions(db: &Arc<Database>) {
|
|||
&[
|
||||
ExtensionMetadata {
|
||||
id: "ext2".into(),
|
||||
name: "Extension Two".into(),
|
||||
version: "0.2.0".into(),
|
||||
authors: vec!["marshall".into()],
|
||||
description: "a great extension".into(),
|
||||
repository: "ext2/repo".into(),
|
||||
published_at: t0,
|
||||
manifest: rpc::ExtensionApiManifest {
|
||||
name: "Extension Two".into(),
|
||||
version: "0.2.0".into(),
|
||||
authors: vec!["marshall".into()],
|
||||
description: Some("a great extension".into()),
|
||||
repository: "ext2/repo".into(),
|
||||
schema_version: Some(0),
|
||||
wasm_api_version: None,
|
||||
},
|
||||
published_at: t0_chrono,
|
||||
download_count: 7
|
||||
},
|
||||
ExtensionMetadata {
|
||||
id: "ext1".into(),
|
||||
name: "Extension One".into(),
|
||||
version: "0.0.3".into(),
|
||||
authors: vec!["max".into(), "marshall".into()],
|
||||
description: "a real good extension".into(),
|
||||
repository: "ext1/repo".into(),
|
||||
published_at: t0,
|
||||
manifest: rpc::ExtensionApiManifest {
|
||||
name: "Extension One".into(),
|
||||
version: "0.0.3".into(),
|
||||
authors: vec!["max".into(), "marshall".into()],
|
||||
description: Some("a real good extension".into()),
|
||||
repository: "ext1/repo".into(),
|
||||
schema_version: Some(1),
|
||||
wasm_api_version: None,
|
||||
},
|
||||
published_at: t0_chrono,
|
||||
download_count: 5,
|
||||
},
|
||||
]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue