Skip to content

Commit 6b4e83c

Browse files
committed
feat: Remove magic strings and add enum variants instead
1 parent 7018f25 commit 6b4e83c

File tree

27 files changed

+572
-178
lines changed

27 files changed

+572
-178
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
[workspace]
22
members = [
3-
"autopush-common",
4-
"autoendpoint",
5-
"autoconnect",
6-
"autoconnect/autoconnect-common",
7-
"autoconnect/autoconnect-settings",
8-
"autoconnect/autoconnect-web",
9-
"autoconnect/autoconnect-ws",
10-
"autoconnect/autoconnect-ws/autoconnect-ws-sm",
3+
"autopush-common",
4+
"autoendpoint",
5+
"autoconnect",
6+
"autoconnect/autoconnect-common",
7+
"autoconnect/autoconnect-settings",
8+
"autoconnect/autoconnect-web",
9+
"autoconnect/autoconnect-ws",
10+
"autoconnect/autoconnect-ws/autoconnect-ws-sm",
1111
]
1212
resolver = "2"
1313

1414
[workspace.package]
1515
version = "1.74.3"
1616
authors = [
17-
"Ben Bangert <[email protected]>",
18-
"JR Conlin <[email protected]>",
19-
"Phil Jenvey <[email protected]>",
20-
"Alex Crichton <[email protected]>",
21-
"Mark Drobnak <[email protected]>",
17+
"Ben Bangert <[email protected]>",
18+
"JR Conlin <[email protected]>",
19+
"Phil Jenvey <[email protected]>",
20+
"Alex Crichton <[email protected]>",
21+
"Mark Drobnak <[email protected]>",
2222
]
2323
edition = "2021"
2424
rust-version = "1.86.0"
@@ -49,19 +49,19 @@ env_logger = "0.11"
4949
fernet = "0.2.0"
5050
futures = { version = "0.3", features = ["compat"] }
5151
futures-util = { version = "0.3", features = [
52-
"async-await",
53-
"compat",
54-
"sink",
55-
"io",
52+
"async-await",
53+
"compat",
54+
"sink",
55+
"io",
5656
] }
5757
futures-locks = "0.7"
5858
hex = "0.4.2"
5959
httparse = "1.3"
6060
hyper = "1.6"
6161
lazy_static = "1.4"
6262
log = { version = "0.4", features = [
63-
"max_level_debug",
64-
"release_max_level_info",
63+
"max_level_debug",
64+
"release_max_level_info",
6565
] }
6666
mockall = "0.13"
6767
mozsvc-common = "0.2"
@@ -70,7 +70,7 @@ rand = "0.9"
7070
regex = "1.4"
7171
reqwest = { version = "0.12", features = ["json", "blocking"] }
7272
sentry = { version = "0.36", features = [
73-
"debug-logs",
73+
"debug-logs",
7474
] } # Using debug-logs avoids https://github.com/getsentry/sentry-rust/issues/237
7575
sentry-core = { version = "0.36" }
7676
sentry-actix = "0.36"
@@ -79,9 +79,9 @@ serde = "1.0"
7979
serde_derive = "1.0"
8080
serde_json = "1.0"
8181
slog = { version = "2.7", features = [
82-
"dynamic-keys",
83-
"max_level_trace",
84-
"release_max_level_info",
82+
"dynamic-keys",
83+
"max_level_trace",
84+
"release_max_level_info",
8585
] }
8686
slog-async = "2.6"
8787
slog-envlogger = "2.2.0"
@@ -90,6 +90,7 @@ slog-scope = "4.4"
9090
slog-stdlog = "4.1"
9191
slog-term = "2.6"
9292
strum = { version = "0.27", features = ["derive"] }
93+
strum_macros = "0.27"
9394
thiserror = "2.0"
9495
tokio = "1.38"
9596
tokio-compat-02 = "0.2"
@@ -106,6 +107,3 @@ autoconnect_web = { path = "./autoconnect/autoconnect-web" }
106107
autoconnect_ws = { path = "./autoconnect/autoconnect-ws" }
107108
autoconnect_ws_clientsm = { path = "./autoconnect/autoconnect-ws/autoconnect-ws-clientsm" }
108109
autopush_common = { path = "./autopush-common", features = ["bigtable"] }
109-
110-
[profile.release]
111-
debug = 1

autoconnect/autoconnect-common/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ serde_derive.workspace = true
2020
serde_json.workspace = true
2121
slog.workspace = true
2222
slog-scope.workspace = true
23+
strum.workspace = true
24+
strum_macros.workspace = true
2325
uuid.workspace = true
2426

2527

autoconnect/autoconnect-common/src/broadcast.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use std::collections::HashMap;
1414

1515
use serde_derive::{Deserialize, Serialize};
16+
use strum_macros::{AsRefStr, Display};
1617

1718
use autopush_common::errors::{ApcErrorKind, Result};
1819

@@ -72,6 +73,12 @@ struct BroadcastRevision {
7273
broadcast: BroadcastKey,
7374
}
7475

76+
#[derive(Debug, Clone, Copy, PartialEq, Eq, AsRefStr, Display)]
77+
pub enum BroadcastErrorKind {
78+
#[strum(serialize = "Broadcast not found")]
79+
NotFound,
80+
}
81+
7582
/// A provided Broadcast/Version used for `BroadcastSubsInit`, client comparisons, and outgoing
7683
/// deltas
7784
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
@@ -85,7 +92,7 @@ impl Broadcast {
8592
pub fn error(self) -> Broadcast {
8693
Broadcast {
8794
broadcast_id: self.broadcast_id,
88-
version: "Broadcast not found".to_string(),
95+
version: BroadcastErrorKind::NotFound.to_string(),
8996
}
9097
}
9198
}
@@ -191,7 +198,9 @@ impl BroadcastChangeTracker {
191198
let key = self
192199
.broadcast_registry
193200
.lookup_key(&broadcast.broadcast_id)
194-
.ok_or(ApcErrorKind::BroadcastError("Broadcast not found".into()))?;
201+
.ok_or(ApcErrorKind::BroadcastError(
202+
BroadcastErrorKind::NotFound.to_string(),
203+
))?;
195204

196205
if let Some(ver) = self.broadcast_versions.get_mut(&key) {
197206
if *ver == broadcast.version {
@@ -200,7 +209,9 @@ impl BroadcastChangeTracker {
200209
*ver = broadcast.version;
201210
} else {
202211
trace!("📢 Not found: {b_id}");
203-
return Err(ApcErrorKind::BroadcastError("Broadcast not found".into()).into());
212+
return Err(
213+
ApcErrorKind::BroadcastError(BroadcastErrorKind::NotFound.to_string()).into(),
214+
);
204215
}
205216

206217
trace!("📢 New version of {b_id}");

autoconnect/autoconnect-common/src/megaphone.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use std::{collections::HashMap, error::Error, io, sync::Arc, time::Duration};
22

33
use actix_web::rt;
4-
use cadence::{CountedExt, StatsdClient};
4+
use autopush_common::metric_name::MetricName;
5+
use autopush_common::metrics::StatsdClientExt;
6+
use cadence::StatsdClient;
57
use serde_derive::Deserialize;
68
use tokio::sync::RwLock;
79

@@ -39,7 +41,9 @@ pub async fn init_and_spawn_megaphone_updater(
3941
if let Err(e) = updater(&broadcaster, &http, &url, &token).await {
4042
report_updater_error(&metrics, e);
4143
} else {
42-
metrics.incr_with_tags("megaphone.updater.ok").send();
44+
metrics
45+
.incr_with_tags(MetricName::MegaphoneUpdaterOk)
46+
.send();
4347
}
4448
}
4549
});
@@ -59,7 +63,7 @@ fn report_updater_error(metrics: &Arc<StatsdClient>, err: reqwest::Error) {
5963
"unknown"
6064
};
6165
metrics
62-
.incr_with_tags("megaphone.updater.error")
66+
.incr_with_tags(MetricName::MegaphoneUpdaterError)
6367
.with_tag("reason", reason)
6468
.send();
6569
if reason == "unknown" {

autoconnect/autoconnect-common/src/protocol.rs

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,49 @@ use std::collections::HashMap;
1010
use std::str::FromStr;
1111

1212
use serde_derive::{Deserialize, Serialize};
13+
use strum_macros::{AsRefStr, Display, EnumString};
1314
use uuid::Uuid;
1415

1516
use autopush_common::notification::Notification;
1617

18+
/// Message types for WebPush protocol messages.
19+
///
20+
/// This enum should be used instead of string literals when referring to message types.
21+
/// String serialization is handled automatically via the strum traits.
22+
///
23+
/// Example:
24+
/// ```
25+
/// use autoconnect_common::protocol::MessageType;
26+
///
27+
/// let message_type = MessageType::Hello;
28+
/// let message_str = message_type.as_str(); // Returns "hello"
29+
/// ```
30+
#[derive(Debug, Clone, Copy, PartialEq, Eq, AsRefStr, Display, EnumString)]
31+
#[strum(serialize_all = "snake_case")]
32+
pub enum MessageType {
33+
Hello,
34+
Register,
35+
Unregister,
36+
BroadcastSubscribe,
37+
Ack,
38+
Nack,
39+
Ping,
40+
Notification,
41+
Broadcast,
42+
}
43+
44+
impl MessageType {
45+
/// Converts the enum to its string representation
46+
pub fn as_str(&self) -> &str {
47+
self.as_ref()
48+
}
49+
50+
/// Returns the expected message type string for error messages
51+
pub fn expected_msg(&self) -> String {
52+
format!(r#"Expected messageType="{}""#, self.as_str())
53+
}
54+
}
55+
1756
#[derive(Debug, Eq, PartialEq, Serialize)]
1857
#[serde(untagged)]
1958
pub enum BroadcastValue {
@@ -69,6 +108,21 @@ pub enum ClientMessage {
69108
Ping,
70109
}
71110

111+
impl ClientMessage {
112+
/// Get the message type of this message
113+
pub fn message_type(&self) -> MessageType {
114+
match self {
115+
ClientMessage::Hello { .. } => MessageType::Hello,
116+
ClientMessage::Register { .. } => MessageType::Register,
117+
ClientMessage::Unregister { .. } => MessageType::Unregister,
118+
ClientMessage::BroadcastSubscribe { .. } => MessageType::BroadcastSubscribe,
119+
ClientMessage::Ack { .. } => MessageType::Ack,
120+
ClientMessage::Nack { .. } => MessageType::Nack,
121+
ClientMessage::Ping => MessageType::Ping,
122+
}
123+
}
124+
}
125+
72126
impl FromStr for ClientMessage {
73127
type Err = serde_json::error::Error;
74128

@@ -141,11 +195,22 @@ pub enum ServerMessage {
141195
}
142196

143197
impl ServerMessage {
198+
/// Get the message type of this message
199+
pub fn message_type(&self) -> MessageType {
200+
match self {
201+
ServerMessage::Hello { .. } => MessageType::Hello,
202+
ServerMessage::Register { .. } => MessageType::Register,
203+
ServerMessage::Unregister { .. } => MessageType::Unregister,
204+
ServerMessage::Broadcast { .. } => MessageType::Broadcast,
205+
ServerMessage::Notification(..) => MessageType::Notification,
206+
ServerMessage::Ping => MessageType::Ping,
207+
}
208+
}
209+
144210
pub fn to_json(&self) -> Result<String, serde_json::error::Error> {
145211
match self {
146-
// clients recognize {"messageType": "ping"} but traditionally both
147-
// client/server send the empty object version
148-
ServerMessage::Ping => Ok("{}".to_owned()),
212+
// Traditionally both client/server send the empty object version for ping
213+
ServerMessage::Ping => Ok("{}".to_string()),
149214
_ => serde_json::to_string(self),
150215
}
151216
}

autoconnect/autoconnect-common/src/test_support.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use uuid::Uuid;
22

3+
use crate::protocol::MessageType;
34
use autopush_common::{
45
db::{mock::MockDbClient, User},
56
util::timing::ms_since_epoch,
@@ -13,10 +14,20 @@ pub const DUMMY_CHID: Uuid = Uuid::from_u128(0xdeadbeef_0000_0000_abad_1dea00000
1314

1415
/// A minimal websocket Push "hello" message, used by an unregistered UA with
1516
/// no existing channel subscriptions
16-
pub const HELLO: &str = r#"{"messageType": "hello", "use_webpush": true}"#;
17-
/// A post initial registration response
18-
pub const HELLO_AGAIN: &str = r#"{"messageType": "hello", "use_webpush": true,
19-
"uaid": "deadbeef-0000-0000-deca-fbad00000000"}"#;
17+
pub fn hello_json() -> String {
18+
format!(
19+
r#"{{"messageType": "{}", "use_webpush": true}}"#,
20+
MessageType::Hello.as_str()
21+
)
22+
}
23+
24+
pub fn hello_again_json() -> String {
25+
format!(
26+
r#"{{"messageType": "{}", "use_webpush": true,
27+
"uaid": "deadbeef-0000-0000-deca-fbad00000000"}}"#,
28+
MessageType::Hello.as_str()
29+
)
30+
}
2031

2132
pub const CURRENT_MONTH: &str = "message_2018_06";
2233

autoconnect/autoconnect-web/src/dockerflow.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use actix_web::{
55
web::{self, Data, Json},
66
HttpResponse, ResponseError,
77
};
8-
use cadence::CountedExt;
98
use serde_json::json;
109

1110
use autoconnect_settings::AppState;
11+
use autopush_common::metric_name::MetricName;
12+
use autopush_common::metrics::StatsdClientExt;
1213

1314
use crate::error::ApiError;
1415

@@ -47,7 +48,7 @@ pub async fn health_route(state: Data<AppState>) -> Json<serde_json::Value> {
4748
health["reliability"] = json!(state.reliability.health_check().await.unwrap_or_else(|e| {
4849
state
4950
.metrics
50-
.incr_with_tags("error.redis.unavailable")
51+
.incr_with_tags(MetricName::ErrorRedisUnavailable)
5152
.with_tag("application", "autoconnect")
5253
.send();
5354
error!("🔍🟥 Reliability reporting down: {:?}", e);

0 commit comments

Comments
 (0)