Skip to content

Commit 56c48ea

Browse files
committed
code reviews
1 parent 6b4e83c commit 56c48ea

File tree

10 files changed

+65
-68
lines changed

10 files changed

+65
-68
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,6 @@ autoconnect_web = { path = "./autoconnect/autoconnect-web" }
107107
autoconnect_ws = { path = "./autoconnect/autoconnect-ws" }
108108
autoconnect_ws_clientsm = { path = "./autoconnect/autoconnect-ws/autoconnect-ws-clientsm" }
109109
autopush_common = { path = "./autopush-common", features = ["bigtable"] }
110+
111+
[profile.release]
112+
debug = 1

autoconnect/autoconnect-common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ version.workspace = true
88

99
[dependencies]
1010
actix-web.workspace = true
11+
bytestring.workspace = true
1112
cadence.workspace = true
1213
futures.workspace = true
1314
futures-locks.workspace = true

autoconnect/autoconnect-common/src/protocol.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use autopush_common::notification::Notification;
2525
/// use autoconnect_common::protocol::MessageType;
2626
///
2727
/// let message_type = MessageType::Hello;
28-
/// let message_str = message_type.as_str(); // Returns "hello"
28+
/// let message_str = message_type.as_ref(); // Returns "hello"
2929
/// ```
3030
#[derive(Debug, Clone, Copy, PartialEq, Eq, AsRefStr, Display, EnumString)]
3131
#[strum(serialize_all = "snake_case")]
@@ -42,14 +42,9 @@ pub enum MessageType {
4242
}
4343

4444
impl MessageType {
45-
/// Converts the enum to its string representation
46-
pub fn as_str(&self) -> &str {
47-
self.as_ref()
48-
}
49-
5045
/// Returns the expected message type string for error messages
5146
pub fn expected_msg(&self) -> String {
52-
format!(r#"Expected messageType="{}""#, self.as_str())
47+
format!(r#"Expected messageType="{}""#, self.as_ref())
5348
}
5449
}
5550

@@ -209,7 +204,8 @@ impl ServerMessage {
209204

210205
pub fn to_json(&self) -> Result<String, serde_json::error::Error> {
211206
match self {
212-
// Traditionally both client/server send the empty object version for ping
207+
// Both client and server understand the verbose `{"messageType": "ping"}` and the abbreviated `{}`
208+
// as valid ping messages. The server defaults to the shorter `{}` form.
213209
ServerMessage::Ping => Ok("{}".to_string()),
214210
_ => serde_json::to_string(self),
215211
}

autoconnect/autoconnect-common/src/test_support.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use bytestring::ByteString;
12
use uuid::Uuid;
23

34
use crate::protocol::MessageType;
@@ -14,19 +15,22 @@ pub const DUMMY_CHID: Uuid = Uuid::from_u128(0xdeadbeef_0000_0000_abad_1dea00000
1415

1516
/// A minimal websocket Push "hello" message, used by an unregistered UA with
1617
/// no existing channel subscriptions
17-
pub fn hello_json() -> String {
18+
pub fn hello_json() -> ByteString {
1819
format!(
1920
r#"{{"messageType": "{}", "use_webpush": true}}"#,
20-
MessageType::Hello.as_str()
21+
MessageType::Hello.as_ref()
2122
)
23+
.into()
2224
}
2325

24-
pub fn hello_again_json() -> String {
26+
pub fn hello_again_json() -> ByteString {
2527
format!(
2628
r#"{{"messageType": "{}", "use_webpush": true,
27-
"uaid": "deadbeef-0000-0000-deca-fbad00000000"}}"#,
28-
MessageType::Hello.as_str()
29+
"uaid": "{}"}}"#,
30+
MessageType::Hello.as_ref(),
31+
DUMMY_UAID
2932
)
33+
.into()
3034
}
3135

3236
pub const CURRENT_MONTH: &str = "message_2018_06";

autoconnect/autoconnect-web/src/test.rs

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,10 @@ pub async fn hello_new_user() {
4444
});
4545

4646
let mut framed = srv.ws().await.unwrap();
47-
framed
48-
.send(ws::Message::Text(hello_json().into()))
49-
.await
50-
.unwrap();
47+
framed.send(ws::Message::Text(hello_json())).await.unwrap();
5148

5249
let msg = json_msg(&mut framed).await;
53-
assert_eq!(msg["messageType"], MessageType::Hello.as_str());
50+
assert_eq!(msg["messageType"], MessageType::Hello.as_ref());
5451
assert_eq!(msg["status"], 200);
5552
// Ensure that the outbound response to the client includes the
5653
// `use_webpush` flag set to `true`
@@ -69,12 +66,12 @@ pub async fn hello_again() {
6966

7067
let mut framed = srv.ws().await.unwrap();
7168
framed
72-
.send(ws::Message::Text(hello_again_json().into()))
69+
.send(ws::Message::Text(hello_again_json()))
7370
.await
7471
.unwrap();
7572

7673
let msg = json_msg(&mut framed).await;
77-
assert_eq!(msg["messageType"], MessageType::Hello.as_str());
74+
assert_eq!(msg["messageType"], MessageType::Hello.as_ref());
7875
assert_eq!(msg["uaid"], DUMMY_UAID.as_simple().to_string());
7976
}
8077

@@ -84,7 +81,7 @@ pub async fn unsupported_websocket_message() {
8481

8582
let mut framed = srv.ws().await.unwrap();
8683
framed
87-
.send(ws::Message::Binary(hello_json().into()))
84+
.send(ws::Message::Binary(hello_json().into_bytes()))
8885
.await
8986
.unwrap();
9087

@@ -104,18 +101,12 @@ pub async fn invalid_webpush_message() {
104101
});
105102

106103
let mut framed = srv.ws().await.unwrap();
107-
framed
108-
.send(ws::Message::Text(hello_json().into()))
109-
.await
110-
.unwrap();
104+
framed.send(ws::Message::Text(hello_json())).await.unwrap();
111105

112106
let msg = json_msg(&mut framed).await;
113107
assert_eq!(msg["status"], 200);
114108

115-
framed
116-
.send(ws::Message::Text(hello_json().into()))
117-
.await
118-
.unwrap();
109+
framed.send(ws::Message::Text(hello_json())).await.unwrap();
119110

120111
let item = framed.next().await.unwrap().unwrap();
121112
let ws::Frame::Close(Some(close_reason)) = item else {
@@ -159,12 +150,12 @@ pub async fn direct_notif() {
159150

160151
let mut framed = srv.ws().await.unwrap();
161152
framed
162-
.send(ws::Message::Text(hello_again_json().into()))
153+
.send(ws::Message::Text(hello_again_json()))
163154
.await
164155
.unwrap();
165156

166157
let msg = json_msg(&mut framed).await;
167-
assert_eq!(msg["messageType"], MessageType::Hello.as_str());
158+
assert_eq!(msg["messageType"], MessageType::Hello.as_ref());
168159

169160
app_state
170161
.clients
@@ -180,7 +171,7 @@ pub async fn direct_notif() {
180171

181172
// Is a small sleep/tick needed here?
182173
let msg = json_msg(&mut framed).await;
183-
assert_eq!(msg["messageType"], MessageType::Notification.as_str());
174+
assert_eq!(msg["messageType"], MessageType::Notification.as_ref());
184175
assert_eq!(msg["data"], "foo");
185176
}
186177

@@ -202,7 +193,7 @@ pub async fn broadcast_after_ping() {
202193
.add_broadcast(("foo/bar".to_owned(), "v1".to_owned()).into());
203194
let mut srv = test_server(app_state.clone());
204195

205-
let hello = json!({"messageType": MessageType::Hello.as_str(), "use_webpush": true,
196+
let hello = json!({"messageType": MessageType::Hello.as_ref(), "use_webpush": true,
206197
"broadcasts": {"foo/bar": "v1"}});
207198
let mut framed = srv.ws().await.unwrap();
208199
framed
@@ -211,7 +202,7 @@ pub async fn broadcast_after_ping() {
211202
.unwrap();
212203

213204
let msg = json_msg(&mut framed).await;
214-
assert_eq!(msg["messageType"], MessageType::Hello.as_str());
205+
assert_eq!(msg["messageType"], MessageType::Hello.as_ref());
215206
let broadcasts = msg["broadcasts"]
216207
.as_object()
217208
.expect("!broadcasts.is_object()");
@@ -235,7 +226,7 @@ pub async fn broadcast_after_ping() {
235226
tokio::time::sleep(Duration::from_secs_f32(0.2)).await;
236227
let msg = json_msg(&mut framed).await;
237228
assert_eq!(msg.as_object().map_or(0, |o| o.len()), 2);
238-
assert_eq!(msg["messageType"], MessageType::Broadcast.as_str());
229+
assert_eq!(msg["messageType"], MessageType::Broadcast.as_ref());
239230
let broadcasts = msg["broadcasts"]
240231
.as_object()
241232
.expect("!broadcasts.is_object()");

autoconnect/autoconnect-ws/autoconnect-ws-sm/src/identified/on_client_msg.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ impl WebPushClient {
2323
) -> Result<Vec<ServerMessage>, SMError> {
2424
match msg {
2525
ClientMessage::Hello { .. } => {
26-
// Hello messages should be handled by UnidentifiedClient, not here
27-
Err(SMError::expected_message_type(MessageType::Hello))
26+
Err(SMError::invalid_message("Already Hello'd".to_owned()))
2827
}
2928
ClientMessage::Register { channel_id, key } => {
3029
Ok(vec![self.register(channel_id, key).await?])
@@ -55,7 +54,7 @@ impl WebPushClient {
5554
"uaid" => &self.uaid.to_string(),
5655
"channel_id" => &channel_id_str,
5756
"key" => &key,
58-
"message_type" => MessageType::Register.as_str(),
57+
"message_type" => MessageType::Register.as_ref(),
5958
);
6059
let channel_id = Uuid::try_parse(&channel_id_str).map_err(|_| {
6160
SMError::invalid_message(format!("Invalid channelID: {channel_id_str}"))
@@ -130,7 +129,7 @@ impl WebPushClient {
130129
"uaid" => &self.uaid.to_string(),
131130
"channel_id" => &channel_id.to_string(),
132131
"code" => &code,
133-
"message_type" => MessageType::Unregister.as_str(),
132+
"message_type" => MessageType::Unregister.as_ref(),
134133
);
135134
// TODO: (copied from previous state machine) unregister should check
136135
// the format of channel_id like register does
@@ -163,7 +162,7 @@ impl WebPushClient {
163162
&mut self,
164163
broadcasts: HashMap<String, String>,
165164
) -> Result<Option<ServerMessage>, SMError> {
166-
trace!("WebPushClient:broadcast_subscribe"; "message_type" => MessageType::BroadcastSubscribe.as_str());
165+
trace!("WebPushClient:broadcast_subscribe"; "message_type" => MessageType::BroadcastSubscribe.as_ref());
167166
let broadcasts = Broadcast::from_hashmap(broadcasts);
168167
let mut response: HashMap<String, BroadcastValue> = HashMap::new();
169168

@@ -186,7 +185,7 @@ impl WebPushClient {
186185

187186
/// Acknowledge receipt of one or more Push Notifications
188187
async fn ack(&mut self, updates: &[ClientAck]) -> Result<Vec<ServerMessage>, SMError> {
189-
trace!("✅ WebPushClient:ack"; "message_type" => MessageType::Ack.as_str());
188+
trace!("✅ WebPushClient:ack"; "message_type" => MessageType::Ack.as_ref());
190189
let _ = self
191190
.app_state
192191
.metrics
@@ -220,10 +219,10 @@ impl WebPushClient {
220219
.position(|n| n.channel_id == notif.channel_id && n.version == notif.version);
221220
if let Some(pos) = pos {
222221
debug!(
223-
"✅ Ack (Direct)";
222+
"✅ Ack (Stored)";
224223
"channel_id" => notif.channel_id.as_hyphenated().to_string(),
225224
"version" => &notif.version,
226-
"message_type" => MessageType::Ack.as_str()
225+
"message_type" => MessageType::Ack.as_ref()
227226
);
228227
// Get the stored notification record.
229228
let n = &mut self.ack_state.unacked_stored_notifs[pos];
@@ -272,7 +271,7 @@ impl WebPushClient {
272271
/// Negative Acknowledgement (a Client error occurred) of one or more Push
273272
/// Notifications
274273
fn nack(&mut self, code: Option<i32>) {
275-
trace!("WebPushClient:nack"; "message_type" => MessageType::Nack.as_str());
274+
trace!("WebPushClient:nack"; "message_type" => MessageType::Nack.as_ref());
276275
// only metric codes expected from the client (or 0)
277276
let code = code
278277
.and_then(|code| (301..=303).contains(&code).then_some(code))
@@ -290,7 +289,7 @@ impl WebPushClient {
290289
/// Note this is the WebPush Protocol level's Ping: this differs from the
291290
/// lower level WebSocket Ping frame (handled by the `webpush_ws` handler).
292291
fn ping(&mut self) -> Result<ServerMessage, SMError> {
293-
trace!("WebPushClient:ping"; "message_type" => MessageType::Ping.as_str());
292+
trace!("WebPushClient:ping"; "message_type" => MessageType::Ping.as_ref());
294293
// TODO: why is this 45 vs the comment describing a minute? and 45
295294
// should be a setting
296295
// Clients shouldn't ping > than once per minute or we disconnect them
@@ -311,18 +310,18 @@ impl WebPushClient {
311310
/// method) before proceeding to read the next batch (or potential other
312311
/// actions such as `reset_uaid`).
313312
async fn post_process_all_acked(&mut self) -> Result<Vec<ServerMessage>, SMError> {
314-
trace!("▶️ WebPushClient:post_process_all_acked"; "message_type" => MessageType::Notification.as_str());
313+
trace!("▶️ WebPushClient:post_process_all_acked"; "message_type" => MessageType::Notification.as_ref());
315314
let flags = &self.flags;
316315
if flags.check_storage {
317316
if flags.increment_storage {
318317
debug!(
319318
"▶️ WebPushClient:post_process_all_acked check_storage && increment_storage";
320-
"message_type" => MessageType::Notification.as_str()
319+
"message_type" => MessageType::Notification.as_ref()
321320
);
322321
self.increment_storage().await?;
323322
}
324323

325-
debug!("▶️ WebPushClient:post_process_all_acked check_storage"; "message_type" => MessageType::Notification.as_str());
324+
debug!("▶️ WebPushClient:post_process_all_acked check_storage"; "message_type" => MessageType::Notification.as_ref());
326325
let smsgs = self.check_storage_loop().await?;
327326
if !smsgs.is_empty() {
328327
debug_assert!(self.flags.check_storage);
@@ -340,7 +339,7 @@ impl WebPushClient {
340339
debug_assert!(!self.ack_state.unacked_notifs());
341340
let flags = &self.flags;
342341
if flags.old_record_version {
343-
debug!("▶️ WebPushClient:post_process_all_acked; resetting uaid"; "message_type" => MessageType::Notification.as_str());
342+
debug!("▶️ WebPushClient:post_process_all_acked; resetting uaid"; "message_type" => MessageType::Notification.as_ref());
344343
self.app_state
345344
.metrics
346345
.incr_with_tags(MetricName::UaExpiration)

autoconnect/autoconnect-ws/autoconnect-ws-sm/src/unidentified.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl UnidentifiedClient {
7070
};
7171
debug!(
7272
"👋UnidentifiedClient::on_client_msg {} from uaid?: {:?}",
73-
MessageType::Hello.as_str(),
73+
MessageType::Hello.as_ref(),
7474
uaid
7575
);
7676

@@ -85,7 +85,7 @@ impl UnidentifiedClient {
8585
let uaid = user.uaid;
8686
debug!(
8787
"💬UnidentifiedClient::on_client_msg {}! uaid: {} existing_user: {}",
88-
MessageType::Hello.as_str(),
88+
MessageType::Hello.as_ref(),
8989
uaid,
9090
existing_user,
9191
);
@@ -144,7 +144,7 @@ impl UnidentifiedClient {
144144
async fn get_or_create_user(&self, uaid: Option<Uuid>) -> Result<GetOrCreateUser, SMError> {
145145
trace!(
146146
"❓UnidentifiedClient::get_or_create_user for {}",
147-
MessageType::Hello.as_str()
147+
MessageType::Hello.as_ref()
148148
);
149149
let connected_at = ms_since_epoch();
150150

@@ -199,7 +199,7 @@ impl UnidentifiedClient {
199199
) -> (BroadcastSubs, HashMap<String, BroadcastValue>) {
200200
trace!(
201201
"UnidentifiedClient::broadcast_init for {}",
202-
MessageType::Hello.as_str()
202+
MessageType::Hello.as_ref()
203203
);
204204
let bc = self.app_state.broadcaster.read().await;
205205
let BroadcastSubsInit(broadcast_subs, delta) = bc.broadcast_delta(broadcasts);
@@ -224,13 +224,12 @@ struct GetOrCreateUser {
224224

225225
#[cfg(test)]
226226
mod tests {
227+
use std::str::FromStr;
227228
use std::sync::Arc;
228229

229230
use autoconnect_common::{
230231
protocol::{ClientMessage, MessageType},
231-
test_support::{
232-
hello_again_db, hello_again_json, hello_db, hello_json, DUMMY_CHID, DUMMY_UAID, UA,
233-
},
232+
test_support::{hello_again_db, hello_again_json, hello_db, DUMMY_CHID, DUMMY_UAID, UA},
234233
};
235234
use autoconnect_settings::AppState;
236235

@@ -258,7 +257,7 @@ mod tests {
258257
.unwrap();
259258
assert!(matches!(err.kind, SMErrorKind::InvalidMessage(_)));
260259
// Verify error message contains expected message type
261-
assert!(format!("{}", err).contains(MessageType::Hello.as_str()));
260+
assert!(format!("{}", err).contains(MessageType::Hello.as_ref()));
262261

263262
// Test with Register message
264263
let client = uclient(Default::default());
@@ -272,7 +271,7 @@ mod tests {
272271
.unwrap();
273272
assert!(matches!(err.kind, SMErrorKind::InvalidMessage(_)));
274273
// Verify error message contains expected message type
275-
assert!(format!("{}", err).contains(MessageType::Hello.as_str()));
274+
assert!(format!("{}", err).contains(MessageType::Hello.as_ref()));
276275
}
277276

278277
#[tokio::test]
@@ -294,9 +293,12 @@ mod tests {
294293
db: hello_db().into_boxed_arc(),
295294
..Default::default()
296295
});
297-
// Using hello_json helper ensures consistent message type strings
298-
let raw = hello_json();
299-
let msg = raw.parse::<ClientMessage>().unwrap();
296+
// Ensure that we do not need to pass the "use_webpush" flag.
297+
// (yes, this could just be passing the string, but I want to be
298+
// very explicit here.)
299+
let json = serde_json::json!({"messageType":"hello"});
300+
let raw = json.to_string();
301+
let msg = ClientMessage::from_str(&raw).unwrap();
300302
client.on_client_msg(msg).await.expect("Hello failed");
301303
}
302304

0 commit comments

Comments
 (0)