story-kit: merge 138_bug_no_heartbeat_to_detect_stale_websocket_connections
This commit is contained in:
@@ -29,6 +29,9 @@ enum WsRequest {
|
||||
request_id: String,
|
||||
approved: bool,
|
||||
},
|
||||
/// Heartbeat ping from the client. The server responds with `Pong` so the
|
||||
/// client can detect stale (half-closed) connections.
|
||||
Ping,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -91,6 +94,9 @@ enum WsResponse {
|
||||
status: String,
|
||||
message: String,
|
||||
},
|
||||
/// Heartbeat response to a client `Ping`. Lets the client confirm the
|
||||
/// connection is alive and cancel any stale-connection timeout.
|
||||
Pong,
|
||||
}
|
||||
|
||||
impl From<WatcherEvent> for Option<WsResponse> {
|
||||
@@ -285,6 +291,9 @@ pub async fn ws_handler(ws: WebSocket, ctx: Data<&Arc<AppContext>>) -> impl poem
|
||||
Ok(WsRequest::Cancel) => {
|
||||
let _ = chat::cancel_chat(&ctx.state);
|
||||
}
|
||||
Ok(WsRequest::Ping) => {
|
||||
let _ = tx.send(WsResponse::Pong);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -305,6 +314,9 @@ pub async fn ws_handler(ws: WebSocket, ctx: Data<&Arc<AppContext>>) -> impl poem
|
||||
Ok(WsRequest::Cancel) => {
|
||||
let _ = chat::cancel_chat(&ctx.state);
|
||||
}
|
||||
Ok(WsRequest::Ping) => {
|
||||
let _ = tx.send(WsResponse::Pong);
|
||||
}
|
||||
Ok(WsRequest::PermissionResponse { .. }) => {
|
||||
// Permission responses outside an active chat are ignored.
|
||||
}
|
||||
@@ -385,6 +397,13 @@ mod tests {
|
||||
assert!(matches!(req, WsRequest::Cancel));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_ping_request() {
|
||||
let json = r#"{"type": "ping"}"#;
|
||||
let req: WsRequest = serde_json::from_str(json).unwrap();
|
||||
assert!(matches!(req, WsRequest::Ping));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_permission_response_approved() {
|
||||
let json = r#"{
|
||||
@@ -538,6 +557,13 @@ mod tests {
|
||||
assert_eq!(json["type"], "agent_config_changed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_pong_response() {
|
||||
let resp = WsResponse::Pong;
|
||||
let json = serde_json::to_value(&resp).unwrap();
|
||||
assert_eq!(json["type"], "pong");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_permission_request_response() {
|
||||
let resp = WsResponse::PermissionRequest {
|
||||
|
||||
Reference in New Issue
Block a user