Skip to content

Commit 623ba56

Browse files
committed
refactor(ads-client): use any for simpler telemetry type
1 parent ff2d2c3 commit 623ba56

File tree

7 files changed

+78
-115
lines changed

7 files changed

+78
-115
lines changed

components/ads-client/src/client.rs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::client::ad_response::{
1313
use crate::client::config::AdsClientConfig;
1414
use crate::client::telemetry::ClientOperationEvent;
1515
use crate::error::{RecordClickError, RecordImpressionError, ReportAdError, RequestAdsError};
16-
use crate::http_cache::{CacheOutcome, HttpCache, HttpCacheBuilderError, RequestCachePolicy};
16+
use crate::http_cache::{HttpCache, RequestCachePolicy};
1717
use crate::mars::MARSClient;
1818
use crate::telemetry::Telemetry;
1919
use ad_request::{AdPlacementRequest, AdRequest};
@@ -33,14 +33,7 @@ const DEFAULT_MAX_CACHE_SIZE_MIB: u64 = 10;
3333

3434
pub struct AdsClient<T>
3535
where
36-
T: Telemetry<CacheOutcome>
37-
+ Telemetry<ClientOperationEvent>
38-
+ Telemetry<HttpCacheBuilderError>
39-
+ Telemetry<RecordClickError>
40-
+ Telemetry<RecordImpressionError>
41-
+ Telemetry<ReportAdError>
42-
+ Telemetry<RequestAdsError>
43-
+ Telemetry<serde_json::Error>,
36+
T: Telemetry,
4437
{
4538
client: MARSClient<T>,
4639
context_id_component: ContextIDComponent,
@@ -49,14 +42,7 @@ where
4942

5043
impl<T> AdsClient<T>
5144
where
52-
T: Telemetry<CacheOutcome>
53-
+ Telemetry<serde_json::Error>
54-
+ Telemetry<ClientOperationEvent>
55-
+ Telemetry<HttpCacheBuilderError>
56-
+ Telemetry<RecordClickError>
57-
+ Telemetry<RecordImpressionError>
58-
+ Telemetry<ReportAdError>
59-
+ Telemetry<RequestAdsError>,
45+
T: Telemetry,
6046
{
6147
pub fn new(client_config: AdsClientConfig<T>) -> Self {
6248
let context_id = Uuid::new_v4().to_string();

components/ads-client/src/client/ad_response.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub struct AdResponse<A: AdResponseValue> {
1616
}
1717

1818
impl<A: AdResponseValue> AdResponse<A> {
19-
pub fn parse<T: Telemetry<serde_json::Error> + ?Sized>(
19+
pub fn parse<T: Telemetry>(
2020
data: serde_json::Value,
2121
telemetry: &T,
2222
) -> Result<AdResponse<A>, serde_json::Error> {

components/ads-client/src/client/config.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ use std::sync::Arc;
88
use once_cell::sync::Lazy;
99
use url::Url;
1010

11-
use crate::client::telemetry::ClientOperationEvent;
12-
use crate::error::{RecordClickError, RecordImpressionError, ReportAdError, RequestAdsError};
13-
use crate::http_cache::{CacheOutcome, HttpCacheBuilderError};
1411
use crate::telemetry::Telemetry;
1512

1613
static MARS_API_ENDPOINT_PROD: Lazy<Url> =
@@ -22,14 +19,7 @@ static MARS_API_ENDPOINT_STAGING: Lazy<Url> =
2219

2320
pub struct AdsClientConfig<T>
2421
where
25-
T: Telemetry<CacheOutcome>
26-
+ Telemetry<ClientOperationEvent>
27-
+ Telemetry<HttpCacheBuilderError>
28-
+ Telemetry<RecordClickError>
29-
+ Telemetry<RecordImpressionError>
30-
+ Telemetry<ReportAdError>
31-
+ Telemetry<RequestAdsError>
32-
+ Telemetry<serde_json::Error>,
22+
T: Telemetry,
3323
{
3424
pub environment: Environment,
3525
pub cache_config: Option<AdsCacheConfig>,

components/ads-client/src/ffi/telemetry.rs

Lines changed: 63 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
44
*/
55

6+
use std::any::Any;
67
use std::sync::Arc;
78

89
use crate::client::telemetry::ClientOperationEvent;
@@ -33,83 +34,67 @@ pub struct MozAdsTelemetryWrapper {
3334
pub inner: Arc<dyn MozAdsTelemetry>,
3435
}
3536

36-
impl Telemetry<CacheOutcome> for MozAdsTelemetryWrapper {
37-
fn record(&self, event: &CacheOutcome) {
38-
let label = match event {
39-
CacheOutcome::Hit => "hit",
40-
CacheOutcome::LookupFailed(_) => "lookup_failed",
41-
CacheOutcome::NoCache => "no_cache",
42-
CacheOutcome::MissNotCacheable => "miss_not_cacheable",
43-
CacheOutcome::MissStored => "miss_stored",
44-
CacheOutcome::StoreFailed(_) => "store_failed",
45-
CacheOutcome::CleanupFailed(_) => "cleanup_failed",
46-
};
47-
self.inner.record_http_cache_outcome(label);
48-
}
49-
}
50-
51-
impl Telemetry<serde_json::Error> for MozAdsTelemetryWrapper {
52-
fn record(&self, event: &serde_json::Error) {
53-
let label = "invalid_ad_item";
54-
let value = format!("{}", event);
55-
self.inner.record_deserialization_error(label, &value);
56-
}
57-
}
58-
59-
impl Telemetry<HttpCacheBuilderError> for MozAdsTelemetryWrapper {
60-
fn record(&self, event: &HttpCacheBuilderError) {
61-
let label = match event {
62-
HttpCacheBuilderError::EmptyDbPath => "empty_db_path",
63-
HttpCacheBuilderError::Database(_) => "database_error",
64-
HttpCacheBuilderError::InvalidMaxSize { .. } => "invalid_max_size",
65-
HttpCacheBuilderError::InvalidTtl { .. } => "invalid_ttl",
66-
};
67-
let value = format!("{}", event);
68-
self.inner.record_build_cache_error(label, &value);
69-
}
70-
}
71-
72-
impl Telemetry<RequestAdsError> for MozAdsTelemetryWrapper {
73-
fn record(&self, event: &RequestAdsError) {
74-
let label = "request_ads";
75-
let value = format!("{}", event);
76-
self.inner.record_client_error(label, &value);
77-
}
78-
}
79-
80-
impl Telemetry<RecordClickError> for MozAdsTelemetryWrapper {
81-
fn record(&self, event: &RecordClickError) {
82-
let label = "record_click";
83-
let value = format!("{}", event);
84-
self.inner.record_client_error(label, &value);
85-
}
86-
}
87-
88-
impl Telemetry<RecordImpressionError> for MozAdsTelemetryWrapper {
89-
fn record(&self, event: &RecordImpressionError) {
90-
let label = "record_impression";
91-
let value = format!("{}", event);
92-
self.inner.record_client_error(label, &value);
93-
}
94-
}
95-
96-
impl Telemetry<ReportAdError> for MozAdsTelemetryWrapper {
97-
fn record(&self, event: &ReportAdError) {
98-
let label = "report_ad";
99-
let value = format!("{}", event);
100-
self.inner.record_client_error(label, &value);
101-
}
102-
}
103-
104-
impl Telemetry<ClientOperationEvent> for MozAdsTelemetryWrapper {
105-
fn record(&self, event: &ClientOperationEvent) {
106-
let label = match event {
107-
ClientOperationEvent::New => "new",
108-
ClientOperationEvent::RecordClick => "record_click",
109-
ClientOperationEvent::RecordImpression => "record_impression",
110-
ClientOperationEvent::ReportAd => "report_ad",
111-
ClientOperationEvent::RequestAds => "request_ads",
112-
};
113-
self.inner.record_client_operation_total(label);
37+
impl Telemetry for MozAdsTelemetryWrapper {
38+
fn record(&self, event: &dyn Any) {
39+
if let Some(cache_outcome) = event.downcast_ref::<CacheOutcome>() {
40+
self.inner.record_http_cache_outcome(match cache_outcome {
41+
CacheOutcome::Hit => "hit",
42+
CacheOutcome::LookupFailed(_) => "lookup_failed",
43+
CacheOutcome::NoCache => "no_cache",
44+
CacheOutcome::MissNotCacheable => "miss_not_cacheable",
45+
CacheOutcome::MissStored => "miss_stored",
46+
CacheOutcome::StoreFailed(_) => "store_failed",
47+
CacheOutcome::CleanupFailed(_) => "cleanup_failed",
48+
});
49+
return;
50+
}
51+
if let Some(client_op) = event.downcast_ref::<ClientOperationEvent>() {
52+
self.inner.record_client_operation_total(match client_op {
53+
ClientOperationEvent::New => "new",
54+
ClientOperationEvent::RecordClick => "record_click",
55+
ClientOperationEvent::RecordImpression => "record_impression",
56+
ClientOperationEvent::ReportAd => "report_ad",
57+
ClientOperationEvent::RequestAds => "request_ads",
58+
});
59+
return;
60+
}
61+
if let Some(cache_builder_error) = event.downcast_ref::<HttpCacheBuilderError>() {
62+
self.inner.record_build_cache_error(
63+
match cache_builder_error {
64+
HttpCacheBuilderError::EmptyDbPath => "empty_db_path",
65+
HttpCacheBuilderError::Database(_) => "database_error",
66+
HttpCacheBuilderError::InvalidMaxSize { .. } => "invalid_max_size",
67+
HttpCacheBuilderError::InvalidTtl { .. } => "invalid_ttl",
68+
},
69+
&format!("{}", cache_builder_error),
70+
);
71+
return;
72+
}
73+
if let Some(record_click_error) = event.downcast_ref::<RecordClickError>() {
74+
self.inner
75+
.record_client_error("record_click", &format!("{}", record_click_error));
76+
return;
77+
}
78+
if let Some(record_impression_error) = event.downcast_ref::<RecordImpressionError>() {
79+
self.inner
80+
.record_client_error("record_impression", &format!("{}", record_impression_error));
81+
return;
82+
}
83+
if let Some(report_ad_error) = event.downcast_ref::<ReportAdError>() {
84+
self.inner
85+
.record_client_error("report_ad", &format!("{}", report_ad_error));
86+
return;
87+
}
88+
if let Some(request_ads_error) = event.downcast_ref::<RequestAdsError>() {
89+
self.inner
90+
.record_client_error("request_ads", &format!("{}", request_ads_error));
91+
return;
92+
}
93+
if let Some(json_error) = event.downcast_ref::<serde_json::Error>() {
94+
self.inner
95+
.record_deserialization_error("invalid_ad_item", &format!("{}", json_error));
96+
return;
97+
}
98+
eprintln!("Unsupported telemetry event type: {:?}", event.type_id());
11499
}
115100
}

components/ads-client/src/mars.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
check_http_status_for_error, CallbackRequestError, FetchAdsError, RecordClickError,
1616
RecordImpressionError, ReportAdError,
1717
},
18-
http_cache::{CacheOutcome, HttpCache, HttpCacheError, RequestHash},
18+
http_cache::{HttpCache, HttpCacheError, RequestHash},
1919
telemetry::Telemetry,
2020
RequestCachePolicy,
2121
};
@@ -24,7 +24,7 @@ use viaduct::Request;
2424

2525
pub struct MARSClient<T>
2626
where
27-
T: Telemetry<CacheOutcome> + Telemetry<serde_json::Error>,
27+
T: Telemetry,
2828
{
2929
endpoint: Url,
3030
http_cache: Option<HttpCache>,
@@ -33,7 +33,7 @@ where
3333

3434
impl<T> MARSClient<T>
3535
where
36-
T: Telemetry<CacheOutcome> + Telemetry<serde_json::Error>,
36+
T: Telemetry,
3737
{
3838
pub fn new(environment: Environment, http_cache: Option<HttpCache>, telemetry: Arc<T>) -> Self {
3939
let endpoint = environment.into_mars_url().clone();

components/ads-client/src/telemetry.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
44
*/
55

6-
pub trait Telemetry<A>: Send + Sync {
7-
fn record(&self, event: &A);
6+
use std::any::Any;
7+
8+
pub trait Telemetry {
9+
fn record(&self, event: &dyn Any);
810
}

components/ads-client/src/test_utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
44
*/
55

6-
use std::{collections::HashMap, fmt::Debug};
6+
use std::collections::HashMap;
77

88
use url::Url;
99

@@ -21,8 +21,8 @@ pub const TEST_CONTEXT_ID: &str = "00000000-0000-4000-8000-000000000001";
2121

2222
pub struct PrintAdsTelemetry;
2323

24-
impl<A: Debug> Telemetry<A> for PrintAdsTelemetry {
25-
fn record(&self, event: &A) {
24+
impl Telemetry for PrintAdsTelemetry {
25+
fn record(&self, event: &dyn std::any::Any) {
2626
println!("record: {:?}", event);
2727
}
2828
}

0 commit comments

Comments
 (0)