From b247465965eb4e92a49c6699e6a9b808786a5c99 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Mon, 17 Jul 2023 09:49:42 -0700 Subject: [PATCH] feat(turbopack_core): define trait for diagnostics --- crates/turbopack-core/src/diagnostics/mod.rs | 84 ++++++++++++++++++++ crates/turbopack-core/src/lib.rs | 1 + 2 files changed, 85 insertions(+) create mode 100644 crates/turbopack-core/src/diagnostics/mod.rs diff --git a/crates/turbopack-core/src/diagnostics/mod.rs b/crates/turbopack-core/src/diagnostics/mod.rs new file mode 100644 index 0000000000000..bdf0324275dcb --- /dev/null +++ b/crates/turbopack-core/src/diagnostics/mod.rs @@ -0,0 +1,84 @@ +use std::collections::HashMap; + +use anyhow::Result; +use async_trait::async_trait; +use turbo_tasks::{emit, CollectiblesSource, Upcast, Vc}; + +#[turbo_tasks::value(serialization = "none")] +#[derive(Clone, Debug)] +pub struct PlainDiagnostic { + pub category: String, + pub name: String, + pub payload: HashMap, +} + +#[turbo_tasks::value(transparent)] +pub struct DiagnosticPayload(pub HashMap); + +/// An arbitrary payload can be used to analyze, diagnose +/// Turbopack's behavior. +#[turbo_tasks::value_trait] +pub trait Diagnostic { + /// [NOTE]: Psuedo-reserved; this is not being used currently. + /// The `type` of the diagnostics that can be used selectively filtered by + /// consumers. For example, this could be `telemetry`, or + /// `slow_perf_event`, or something else. This is not strongly typed + /// though; since consumer or implementation may need to define own + /// category. + fn category(&self) -> Vc; + /// Name of the specific diagnostic event. + fn name(&self) -> Vc; + /// Arbitarary payload included in the diagnostic event. + fn payload(&self) -> Vc; + + async fn into_plain(self: Vc) -> Result> { + Ok(PlainDiagnostic { + category: self.category().await?.clone_value(), + name: self.name().await?.clone_value(), + payload: self.payload().await?.clone_value(), + } + .cell()) + } +} + +pub trait DiagnosticExt { + fn emit(self); +} + +impl DiagnosticExt for Vc +where + T: Upcast>, +{ + fn emit(self) { + let diagnostic = Vc::upcast::>(self); + emit(diagnostic); + } +} + +#[async_trait] +pub trait DiagnosticContextExt +where + Self: Sized, +{ + async fn peek_diagnostics(self) -> Result>; +} + +#[async_trait] +impl DiagnosticContextExt for T +where + T: CollectiblesSource + Copy + Send, +{ + async fn peek_diagnostics(self) -> Result> { + Ok(CapturedDiagnostics::cell(CapturedDiagnostics { + diagnostics: self.peek_collectibles().strongly_consistent().await?, + })) + } +} + +/// A list of diagnostics captured with +/// [`DiagnosticsVc::peek_diagnostics_with_path`] and +#[derive(Debug)] +#[turbo_tasks::value] +pub struct CapturedDiagnostics { + pub diagnostics: auto_hash_map::AutoSet>>, +} diff --git a/crates/turbopack-core/src/lib.rs b/crates/turbopack-core/src/lib.rs index 6c74a5de2d808..c4c0f8f9dd429 100644 --- a/crates/turbopack-core/src/lib.rs +++ b/crates/turbopack-core/src/lib.rs @@ -13,6 +13,7 @@ pub mod chunk; pub mod code_builder; pub mod compile_time_info; pub mod context; +pub mod diagnostics; pub mod environment; pub mod error; pub mod file_source;